• Spring框架 --- 深入


    1.Spring IOC

      IOC技术: 控制反转,也叫(依赖注入)

      控制反转:Bean的生命周期不受你控制,而是交给Spring容器管理。

      Spring框架如何利用IOC ?:
              实现了控制反转,Spring容器能帮我们实例化对象,但是并没有做到DI(依赖注入)。

      作用:
            (1) 构建Bean
            (2) Bean之间有依赖关系的话,可以自动帮我们注入
        优势:
            解耦:低耦合,实现面向接口的编程思想

    2.Spring AOP

      动态代理设计模式
          原理和静态代理设计模式没有本质区别:
              被代理类、代理类、被代理和代理类是同一个接口
              代理类的创建过程有区别:
              (1)静态代理:
                      自己编写代理类,代理类自己实现接口
              (2)动态代理:
                      代理类不需要自己编写,他Proxy.newProxyinstance(xx)静态方法
                      在程序执行过程中,动态产生代理类
                      InvocationHandler:里边含有被代理类的引用

       AOP:面向切面的编程

      代理模式主要的作用:
              在业务代码不之情的情况下,切入额外的功能。
        原理:Spring框架具有IOC的功能,所以我们可以利用该功能配置业务Bean 。代理设计模式(动态)
            例如: AccountServiceImpl
            <bean id="AccountServiceImpl" class="service.AccountServiceImpl"></bean>
            然后,Spring框架利用动态代理设计模式创建一个AccountServiceImpl的动态代理对象
            然后就可以在AccountServiceImpl的业务方法的基础上增加相应的功能。
            那Spring把这种技术称为AOP面向切面的编程,其实就是在程序员不知情的情况下在其业务方法上切入额外的功能。

      使用 XML 配置实现具体的操作:
          (1)使用Spring的AOP功能,就需要引入jar  pom.xml
          (2)自己编写切面。很类似于InvocationHandler
              被代理接口   :  业务接口
              被代理类: 实现了被代理口,被代理类也叫业务实现类;
              例子:class CalFfabImpl implements ICalFab

    代码示例:

      Maven项目

      pom.xml 添加的插件  

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.10</version>
            </dependency>       
     <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.10</version>
            </dependency>
                    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>            

      添加资源配置文件 beans.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!-- Spring IOC --> 
       <bean id="calFab" class="day02.aop.CalFabImpl"></bean>
       <bean id="selfAspectRef" class="day02.aop.SelfAspect"></bean>
       
       <!-- Spring Aop 配置切面 -->
       <aop:config>
               <!-- 配置切面 -->
               <aop:aspect ref="selfAspectRef">
                   <!-- 切点  在CalFabImpl类的任何方法上加通知 -->
                   <aop:pointcut expression="execution(* day02.aop.CalFabImpl.*(..))" id="selfPointcut"/>
                   <!-- 通知 -->
                   <aop:before method="testBefore" pointcut-ref="selfPointcut"/>
                   <aop:after method="testAfter" pointcut-ref="selfPointcut"/>
                   <aop:around method="testAround" pointcut-ref="selfPointcut"/>
               </aop:aspect>
       </aop:config>
       
    </beans>

      新建接口 ICalFab.java

     1 /**
     2  * 业务接口
     3  * @author 张泽
     4  */
     5 public interface ICalFab {
     6     
     7     int calFaByLoop(int n);
     8     int calFabByRecursion(int n); 
     9 
    10 }

      新建类实现接口:

    /**
     * 业务实现类:被代理类
     * @author 张泽
     */
    class CalFabImpl implements ICalFab{
        @Override
        public int calFaByLoop(int n) {
            int n1=1,n2= 1,n3=0;
            for (int i = 3; i < n; i++) {
                n3=n1+n2;
                n1=n2;
                n2=n3;
            }
            return n3;
        }
        @Override
        public int calFabByRecursion(int n) {
            if(n==1||n==2) return 1;
            return calFabByRecursion(n-1)+calFabByRecursion(n-2);
            
        }
        
        
    }

      新建类:SelfAspect.java

    import org.aspectj.lang.ProceedingJoinPoint;
    
    /**
     * 自定义功能性切面:利用xml配置实现。
     * @author 张泽
     *
     */
    public class SelfAspect {
        //--通知:Before类型的Advice
        public void testBefore() {
            System.out.println("before do something...");
        }
        //--通知:after类型的通知
        public void testAfter() {
            System.out.println("after do Something...");
        }
        //-- 通知:Around环绕   通知方法的执行点
        public int testAround(ProceedingJoinPoint jp) {
            int result = 0;
            try {
                long start = System.currentTimeMillis();
                result = (int)jp.proceed();    //-- 执行业务方法
                long end = System.currentTimeMillis();
                System.out.println(end-start+"ms");
            } catch (Throwable e) {
                e.printStackTrace();
            }    
            return result;
        }
    } 

      新建调用类:Invoker.java

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * Invoker类
     * 功能切入更加灵活
     * @author 张泽
     *
     */
    public class Invoker {
        public static void main(String[] args) {
            //-- 1. Spring容器
            ApplicationContext ctx =
                    new ClassPathXmlApplicationContext("application.xml");
            //-- 2. 获取业务类
            ICalFab calFab= (ICalFab)ctx.getBean("calFab");
            //-- 3. 调用业务方法
            System.out.println(calFab.calFaByLoop(40));
            System.out.println(calFab.calFabByRecursion(40));
            System.out.println(calFab instanceof ICalFab);
            
        }
    }

      使用 注解 配置实现具体的操作:

        (1) Config类来代替xml的配置
              @EnableAspectJAutoProxy //-- 启用SpringAop的功能
              //-- 启用Spring的IOC功能
              @Configuration
              @ComponentScan({"package1","package2"})
          (2)编写切面。

    代码示例:

      新建接口 ICalFab.java 

    /**
     * 业务接口
     * @author 张泽
     *
     */
    
    public interface ICalFab {
        
        int calFaByLoop(int n);
        int calFabByRecursion(int n); 
    
    }

      新建实现类 CalFabImpl.java

    import org.springframework.stereotype.Component;
    
    /**
     * 业务实现类:被代理类
     * @author 张泽
     */
    @Component    //-- Spring IOC
    class CalFabImpl implements ICalFab{
        @Override
        public int calFaByLoop(int n) {
            int n1=1,n2= 1,n3=0;
            for (int i = 3; i < n; i++) {
                n3=n1+n2;
                n1=n2;
                n2=n3;
            }
            return n3;
        }
        @Override
        public int calFabByRecursion(int n) {
            if(n==1||n==2) return 1;
            return calFabByRecursion(n-1)+calFabByRecursion(n-2);
            
        }
        
        
    }

      新建配置类 AppConfig.java

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * 配置类
     * @author 张泽
     * 实现IOC功能
     * 
     */
    @Configuration
    @EnableAspectJAutoProxy //-- 启用SpringAop的功能
    @ComponentScan("day.annocation")//-- 包名
    public class AppConfig {
    //    @Bean
    //    public ICalFab calFabBean() {
    //        return new CalFabImpl();
    //    }
    }

      新建类:SelfAspect.java

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**
     * 利用标注自定义切面
     * @author 张泽
     *
     */
    @Aspect
    @Component
    public class SelfAspect {
        
        //-- 1. 自定义切点,指定目标方法的位置
        @Pointcut("execution(* day02.annocation.CalFabImpl.*(..))")
        public void selfPointcut() {
            
        }
        //-- 2. 通知
        @Before("selfPointcut()")
        public void testBefore() {
            System.out.println("before do something...");
        }
        
        @After("selfPointcut()")
        public void testAfter() {
            System.out.println("After do something...");
        }
        @Around("selfPointcut()")
        public int testAround(ProceedingJoinPoint jp) {
            int result = 0;
            try {
                long start = System.currentTimeMillis();
                result = (int)jp.proceed();    //-- 执行业务方法
                long end = System.currentTimeMillis();
                System.out.println(end-start+"ms");
            } catch (Throwable e) {
                e.printStackTrace();
            }    
            return result;
        }
    }

      新建类:Invoker.java

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class Invoker {
        public static void main(String[] args) {
            //-- 1.构造Spring容器
            ApplicationContext ctx = 
                    new AnnotationConfigApplicationContext(AppConfig.class);
            //-- 2.获取Beans
            ICalFab calFab =(ICalFab)ctx.getBean("calFabImpl");//-- 默认是类名首字母小写
            calFab.calFabByRecursion(40);
            
            //-- Web服务器启动的时候实例化一个Spring容器,在Web服务器关闭的时候关闭Spring容器
            //-- Servlet的监听
            //-- 容器关闭
            ((AnnotationConfigApplicationContext)ctx).close();
        }
    }

    3.Spring Test


         Spring 的测试框架建立在JUnit测试框架基础上的,它是对JUnit的再次封装。

    使用:

      配置文件 pom.xml 引入插件

    <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12-beta-3</version>
                <scope>test</scope>
            </dependency>
            <!-- Spring Test -->
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.1.7.RELEASE</version>
                <scope>test</scope>
            </dependency>

    示例测试工程的代码:

    /**
     * 业务接口
     * @author 张泽
     *
     */
    
    public interface IUserService {
        void login();
    }
    import org.springframework.stereotype.Component;
    
    /**
     * 业务实现类
     * @author 张泽
     *
     */
    @Component
    public class UserServiceImpl implements IUserService {
    
        @Override
        public void login() {
            System.out.println("login success");
            
        }
    
    }
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * Spring配置
     * @author 张泽
     *
     */
    @Configuration
    @ComponentScan("day03")
    public class AppConfig {
        
        @Bean("hello")
        public String hello() {
            return "hello";
        }
    }
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * 调用
     * @author 张泽
     *
     */
    public class Invoker {
        public static void main(String[] args) {
            //-- Spring COntainer
            ApplicationContext ctx = 
                    new AnnotationConfigApplicationContext(AppConfig.class);
            //-- 2.
            System.out.println(ctx.getBean("hello"));
        }
    }

    JUnit测试代码:

    /**
     * 1. 先利用JUnit做单元测试
     * @author 张泽
     *
     */
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class TestDemo {
        private ApplicationContext ctx;
        
        @Before
        public void before() {
            ctx = new AnnotationConfigApplicationContext(AppConfig.class);    
        }
        
        @Test
        public void test() {
            System.out.println(ctx.getBean("hello"));
        }
        
        
    }
    利用Spring test 框架测试:
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    /**
     * 2. 利用Spring test 框架
     * 
     * @RunWith: 实例化Spring容器
     * @ContextConfiguration: 指定Spring容器需要的配置类
     * 以后你会很少看到Spring容器了
     * 
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes= {AppConfig.class})
    public class TestSpringDemo {
        @Autowired
        private String hi;
        @Autowired
        private IUserService userService;
        
        @Test
        public void test() {
            System.out.println(hi);
        }
        @Test
        public void test1() {
            userService.login();
        }
    }

    该项目的配置文件:pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.uek.course</groupId>
        <artifactId>spring-app</artifactId>
        <version>0.0.1</version>
        <packaging>war</packaging>
    
        <!-- 2. 项目属性配置 -->
        <properties>
            <!-- 项目编码使用UTF-8 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- 忽略掉web.xml文件 ,因为我们使用servlet3.0开发web项目 -->
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <spring.version>5.1.7.RELEASE</spring.version>
        </properties>
        <!-- 3. 配置项目所需要的第三方jar 包 -->
        <dependencies>
            <!-- servlet api -->
            <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
    
            <!-- MySQL数据库连接池 -->
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>
    
            <!-- Druid -->
            <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.20</version>
            </dependency>
            <!-- 单元测试 -->
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12-beta-3</version>
                <scope>test</scope>
            </dependency>
            <!-- Spring Test -->
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>
            
            
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.10</version>
            </dependency>
            
            
            <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.10</version>
            </dependency>
                    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>
            
        
        
        </dependencies>
    
    
    
        <!-- 配置构建插件 -->
        <build>
            <plugins>
                <plugin>
                    <!-- 编译插件 -->
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <!-- Tomcat 插件 -->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <port>8080</port>
                        <path>/airsys</path>
                        <!-- 实现热部署,不需要每次修改代码后都重新启动Tomcat -->
                        <contextReloadable>true</contextReloadable>
                    </configuration>
                </plugin>
    
    
            </plugins>
        </build>
    </project>
  • 相关阅读:
    如何在C#中获得input文本框中的值
    多控件时,自适应布局(dl dd td )
    jquery easyui DataGrid
    报表文本字段钻取使用超链接(URL)的用法 (转)
    rabbitMQ队列使用及常用命令
    java集合操作
    Java集合框架总结(4)——List接口的使用
    Java集合框架总结(3)——TreeSet类的排序问题
    Java HashMap 分析之二:Hash code
    Java HashMap 分析之四:查找和内存使用
  • 原文地址:https://www.cnblogs.com/zhangze-lifetime/p/11768566.html
Copyright © 2020-2023  润新知