使用多种方式实现Ioc

  使用构造注入    

    构造注入是一种高内聚的体现,特别是针对有些属性需要在对象在创建时候赋值,且后续不允许修改(不提供setter方法)

    实例:

      Greeting类:

        

      配置applicationContext.xml文件:

         

      测试:

        

      结果:  

        

    注意点:

      一个<constructor-arg>元素表示构造方法的一个参数,且使用时不区分顺序。当构造方法的参数出现混淆,无法区分时,可以通过<constructor-arg>元素的index属性指定该参数的位置索引,位置从0开始。<constructor-arg>元素还提供了type属性用来指定参数的类型,避免字符串和基本数据类型的混淆。    

      构造注入的时效性好,在对象实例化就得到所依赖的对象,便于在对象的初始化方法中使用依赖对象;但受限于方法重载的形式,使用灵活性不足。设值注入使用灵活,但时效性不足,并且大量的setter访问器增加了类的复杂性。Spring并不倾向于某种注入方式,用户应该根据实际情况进行合理的选择。

  使用p命名空间注入

p命名空间的特点是使用属性而不是子元素的形式配置Bean的属性,从而简化了Bean的配置,使用传统的<property>子元素配置的代码

 

实例:

  Greeting类:

    

  xml文件:

    

  测试:

    

  结果:

    

注意:

  需要注意的是,p名称空间没有标准的XML格式定义灵活,比如说,bean的属性名是以Ref结尾的,那么采用p名称空间定义就会导致冲突,而采用标准的XML格式定义则不会出现这种问题。这里我们提醒大家在项目中还是仔细权衡来决定到底采用那种方式,同时也可以在团队成员都理解不同的定义方式的基础上,在项目中根据需要同时选择三种定义方式。

  P命名空间注入的方式也是使用setter方式注入,所有POJO类中必须存在对应的set方法

  注入不同的数据类型

    

    实例

      编写Collection类:

        

      编写xml文件:

        

      测试:

        

      结果:

        

代理

  静态代理

静态代理需要代理对象和目标对象实现一样的接口;

优点:

可以在不修改目标对象的前提下扩展目标对象的功能;

缺点:

1. 冗余,由于代理对象要实现与目标对象一致的接口,会产生过多的代理类;

2. 不易维护,一旦接口增加的方法,目标对象与代理都要进行修改;

实例:

  DoSomeService接口(抽象主题):

    

  DoSomeServiceImpl实现类(真实主题):

    

  Subject代理类:

     

  测试:

    

 

  结果:

  

  JDK动态代理

JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用;

实例:

  DoSomeService接口:

    

 

  DoSomeServiceImpl实现类:

    

  DoSomeHandler代理类:

    

  测试:

    

  结果:

    

结果:

  1、因为利用JDKProxy生成的代理类实现了接口,所以目标类中所有的方法在代理类中都有。   

  2、生成的代理类的所有的方法都拦截了目标类的所有的方法。而拦截器中invoke方法的内容正好就是代理类的各个方法的组成体。 

  3、利用JDKProxy方式必须有接口的存在。 

        4、invoke方法中的三个参数可以访问目标类的被调用方法的API、被调用方法的参数、被调用方法的返回类型。

  CGLIB动态代理

cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理

实例:

  DoSomeServiceImpl实现类:

    不需要编写接口

    

  CGLIBHandler代理类:

    

  测试:

    

  结果:

           

       总结:

1、 CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 

2、 用CGlib生成代理类是目标类的子类。 

3、 用CGlib生成 代理类不需要接口 

4、 用CGLib生成的代理类重写了父类的各个方法。 

5、 拦截器中的intercept方法内容正好就是代理类中的方法体

 

 posted on 2019-10-28 14:14  wnwn  阅读(188)  评论(0编辑  收藏  举报