• 我的Spring学习记录(二)


    本篇就简单的说一下Bean的装配和AOP
    本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的

    1. 使用setter方法和构造方法装配Bean

    1.1 前期准备

    使用setter方法注入依赖其实在上一篇中已经遇到过了主要通过property在bean中进行注入

    	<!--声明一个bean并且指定相应的类-->
        <bean name="dog" class="cn.lger.domain.Dog">
            <property name="name" value="小美"/>
            <property name="breed" value="土狗"/>
            <property name="sex" value="母"/>
        </bean>
    

    上面在bean中使用 property 进行配置,用法是<property name="对象中的属性名" value="基本类型(与属性相互对应)">
    但是,除了基本类型,对象这些复杂类型要怎么办?

    比如有下面的一个实体类:Man

    public class Man {
    
        private Dog dog;
        private Dog dog2;
    
        /**
         * 这里因为使用了有参的构造函数,所以需要写入无参构造函数
         */
        public Man(){
    
        }
    	/**
    	 * 提供给Spring容器进行注入dog属性,这里将值赋值给dog2
    	 */
        public Man(Dog dog) {
            this.dog2 = dog;
        }
        
        public Dog getDog() {
            return dog;
        }
    
        public void setDog(Dog dog) {
            this.dog = dog;
        }
    
        public void walkTheDog(){
            System.out.println("遛"+dog.getName());
            System.out.println("遛"+dog2.getName());
        }
    }
    

    这个Man有两只Dog,此人要去遛狗,我们现在就帮助他获得dog
    这里我们在配置文件中配置两个dog的bean,配置如下:

    	<bean name="dog" class="cn.lger.domain.Dog">
            <property name="name" value="小美"/>
            <property name="breed" value="土狗"/>
            <property name="sex" value="母"/>
        </bean>
    
        <bean name="dog2" class="cn.lger.domain.Dog">
            <property name="name" value="小美2"/>
            <property name="breed" value="土狗"/>
            <property name="sex" value="母"/>
        </bean>
    

    这里是关于Man获取到两只dog的过程,也是bean的装配过程,Man这个bean的声明过程

    	<bean name="man" class="cn.lger.domain.Man">
            <!--通过ref映射将dog属性注入-->
            <property name="dog" ref="dog"/>
            <!--通过构造函数注入-->
            <constructor-arg ref="dog2"/>
        </bean>
    

    首先我们是使用了setter方法注入我们的bean-->dog,这里我们只需要将value改为ref 就可以使用复杂类型的注入工作了,但是有一个前提是你所需要注入的bean当然是由Spring管理了
    然后是使用了构造函数进行注入,这里就要求我们在生成JavaBean的使用需要提供相应的构造方法,上面给出的Man中有注释,经过构造方法后dog2属性将会产生一个叫小美2 的狗狗

    1.2 代码测试

    public class TestWiring {
    
        /**
         * 测试通过xml文件装配Bean到Man类
         */
         @Test
        public void test01(){
            ClassPathXmlApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            Man man = applicationContext.getBean(Man.class);
            man.walkTheDog();
        }
    }
    
    //打印结果:遛小美
    //        遛小美2
    

    当我们的Man 去遛狗walkTheDog()的时候这时候控制台打印的信息遛小美 遛小美2 让我们知道注入成功了

    1.3 小结

    我们需要明白,可以使用Spring这种在获取对象之前容器的加工能力获取一个有初始值的对象,可以方便我们的开发。每一个获取到的Bean都需要初始值的话这样我们可以解放很多劳动力,装配还可以通过SpEL(Spring Expression Language)这种表达式去注入一些东西,比如:dog2中的<property name="sex" value="#{dog.sex}"/>,当然了,如果有机会的话我们可以一起探讨一下这个东西
    还有就是,这里我所给出的装配Bean是一个简单的装配工作,还有集合(List、Map....)、工厂等方面的装配没有多做介绍,下面文章结束时会给出链接,里面会有装配方面更为详细的解释和操作:-)

    2. AOP的使用

    2.1 前期准备

    在编程之前我们需要了解几个概念,这些概念性的东西我不是很喜欢,它总是让人混淆,或者有点烦。这里我用了自己的理解方式去解释

    • 通知(Advice): 这可以理解为一段代码片,这段代码要让很多没有联系的对象用上,比如数据库中的连接开启与关闭,日志功能等,我们把这些代码使用Spring AOP用在其他对象的方法之前或者之后,这些代码块就可以称之为通知

    • 连接点(Joincut): 就是对象方法在使用时是通过Spring调用通知的地方叫做连接点

    • 切点(Pointcut): 就是对象方法在使用时是明确通过Spring调用通知的地方叫做切点,就是说已经能够基本的确定这里需要插入一个通知

    • 切面(Aspect): 切面切点通知的结合,就是说一个切面就是通过通知 知道要干什么和切点的在哪里干

    • 织入(Weaving): 织入可以理解成一个过程,是通知被应用到到切点的这一个过程

    当然了你可以去看下别人对这些概念的解释
    http://www.cnblogs.com/hongwz/p/5764917.html
    http://www.importnew.com/20748.html

    看了以上的概念是不是对于AOP有了犯迷糊,是这样的,概念的东西还是需要捣鼓一下,其实我也不是很了解,但是,我们要用实例、实践去增加我们的理解,如果别人要我们解释总不能一行一行代码的说出来,同行之间总是要用一些术语交流的嘛,好,废话不说,继续AOP。
    我们现在有一个Man,他现在要去上班了,但是又要去遛狗!!怎么办?可以请一个代理人啊,帮我们的Man去遛狗就行了。

    pom.xml代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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>cn.lger</groupId>
        <artifactId>spring-demo</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>spring-base</module>
        </modules>
    
        <properties>
            <spring.version>4.3.10.RELEASE</spring.version>
        </properties>
    
        <dependencies>
            <!-- 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.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
    		<!--需要使用aop除了引入以上核心部分还要引入下面的两个依赖-->
    		<dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
        </dependencies>
    
    
    </project>
    

    Man的代码如下:

    public class Man {
    
        public void noFreeTime(){
            System.out.println("狗主人(被代理人)上班了");
        }
    
    }
    
    

    代理人Proxy的代码如下:

    public class Proxy {
    
        public void before(){
            System.out.println("代理人去被代理人家里牵狗,然后遛狗");
        }
    
        public void after(){
            System.out.println("代理人带狗狗回家");
        }
    
    }
    

    配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--因为需要用到aop,所以需要引入新的约束,与上一篇的略有不同-->
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           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/aop
            http://www.springframework.org/schema/aop/spring-aop-4.0.xsd ">
    
    
        <bean name="man" class="cn.lger.domain.Man" />
    
        <!--这是一个代理遛狗的人-->
        <bean class="cn.lger.proxy.Proxy" name="proxy"/>
    
        <!--
            关于aop:pointcut的规则
            <aop:pointcut id="walkTheDog" expression="execution(* cn.lger.domain.Man.noFreeTime())"/>
            id->pointcut标识,具有唯一性
            expression是填入一个表达式,表达式中可以使用的有execution()/within()...
            我们这里使用的是execution(),里面的填入是一个关于切入点的信息比如我要Man中的所有方法都能被代理则
            我们可以一步步推出来,如下:
            void cn.lger.domain.Man.noFreeTime()//public 可以不写
            * cn.lger.domain.Man.noFreeTime()//* 返回任意类型
            * cn.lger.domain.Man.*(..)//任意方法、任意参数
        -->
        <!--配置aop-->
        <aop:config>
            <!--切入点-->
            <aop:pointcut id="walkTheDog" expression="execution(* cn.lger.domain.Man.*(..))"/>
            <!--切面-->
            <aop:aspect id="proxy" ref="proxy">
                <aop:before method="before" pointcut-ref="walkTheDog"/>
                <aop:after method="after" pointcut-ref="walkTheDog"/>
                <!--这里的method除了上面的after和before还有其他的,可以google或者百度,当然看文档也是可以的-->
            </aop:aspect>
    
        </aop:config>
    
    
    </beans>
    

    2.2 代码测试

    	/**
         * 测试AOP是否配置成功
         */
        @Test
        public void test01(){
            ClassPathXmlApplicationContext context =
                    new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            Man man = context.getBean(Man.class);
            man.noFreeTime();
        }
        //打印结果
        //    代理人去被代理人家里牵狗,然后遛狗
    	//    狗主人上班了
    	//    代理人带狗狗回家
    

    通过以上的代码测试,说明了在执行noFreeTime()的时候就会执行我们在配置中配置的proxy.before()proxy.after()方法。为什么会这样,这其实和我们Java学习中的动态代理是差不多的,但是Spring的实现更为复杂,它不要求我们实现什么接口,它是基于cglib动态代理的,这里就不作展开,可以自己了解。

    以上的代码(包括上一篇)都可以在github下载

    可能自己知识储备不是充足,也有一些错误,给出以下链接可供学习
    关于Spring装配
    |- http://www.cnblogs.com/jingmoxukong/p/4532680.html
    |- http://www.cnblogs.com/DeepLearing/p/5670516.html
    |- http://www.cnblogs.com/mesopotamia/p/4950927.html
    |- http://www.cnblogs.com/mlj5288/articles/4535451.html
    关于Spring AOP
    |- http://www.cnblogs.com/hongwz/p/5764917.html
    |- http://www.cnblogs.com/frankliiu-java/archive/2010/01/05/1639664.html
    |- http://blog.csdn.net/u010987379/article/details/52152925

  • 相关阅读:
    Docker集群管理之Swarm介绍
    【响应式编程的思维艺术】 (1)Rxjs专题学习计划
    【Angular专题】 (3)装饰器decorator,一块语法糖
    angularjs1.X进阶笔记(3)——如何重构controller
    【Angular专题】——(2)【译】Angular中的ForwardRef
    【Angular专题】——(1)Angular,孤傲的变革者
    00067_字符串类中涉及正则表达式的常用方法
    Web编辑器 图片粘贴上传,实现图文粘贴,图片自动上传
    wangEditor 图片粘贴上传,实现图文粘贴,图片自动上传
    批量下载文件示例
  • 原文地址:https://www.cnblogs.com/lger/p/7575429.html
Copyright © 2020-2023  润新知