`

IOC之方法注入讲解

阅读更多

   林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

       方法注入在我看来就是为了实现在单例类中取得不同的实例类对象。

        当一个Bean依赖的Bean和自己生命周期不同的时候:如Bean A依赖Bean B,Bean A 是singleton,如果需要在Bean A每次用到Bean B的时候都用一个Bean B的新的实例(注意是新的),即使通过在配置文件设置Bean B的 property或者 contructor-arg是不能实现的.这时候只能在Bean A中用Bean B的时候动态得到。

       或者可以这么说, 调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。幸运的是,Spring提供了如下三种解决的方案:

 

  • 放弃控制反转:通过实现ApplicationContextAware接口让bean A能够感知bean 容器,并且在需要的时候通过使用getBean("B")方式向容器请求一个新的bean B实例。
  • Lookup方法注入:Lookup方法注入利用了容器的覆盖受容器管理的bean方法的能力,从而返回指定名字的bean实例。
  • 自定义方法的替代方案:该注入能使用bean的另一个方法实现去替换自定义的方法。

       放弃控制反转的方法比较不方便,一般都不会这么做,所以这里我就不讲了,下面还是来看看lookup方法和replace方法吧!

本文工程免费下载

一、lookup方法注入

        Lookup方法注射指容器能够重写容器中bean的抽象或具体方法,返回查找容器中其他bean的结果。 被查找的bean在上面描述的场景中通常是一个non-singleton bean (尽管也可以是一个singleton的)。Spring通过使用CGLIB库在客户端的类之上修改二进制码, 从而实现上述的场景要求。

        理解:“Lookup方法”可以使Spring替换一个bean原有的,获取其它对象具体的方法,并自动返回在容器中的查找结果。

下面来看看个例子吧。

定义一个House.java:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.mucfc;  
  2. public class House {  
  3.     private String houseSize;  
  4.     private String housePosition;  
  5.     private String housePrice;  
  6.     public String getHouseSize() {  
  7.         return houseSize;  
  8.     }  
  9.     public void setHouseSize(String houseSize) {  
  10.         this.houseSize = houseSize;  
  11.     }  
  12.     public String getHousePosition() {  
  13.         return housePosition;  
  14.     }  
  15.     public void setHousePosition(String housePosition) {  
  16.         this.housePosition = housePosition;  
  17.     }  
  18.     public String getHousePrice() {  
  19.         return housePrice;  
  20.     }  
  21.     public void setHousePrice(String housePrice) {  
  22.         this.housePrice = housePrice;  
  23.     }  
  24.     public String toString(){  
  25.         return "房子大小:"+houseSize+" 房子位置:"+housePosition+" 房子价格:"+housePrice;  
  26.     }  
  27. }  

然后定义一个每次都获得一个house对象的类MaginHouse.java,

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public interface MaginHouse {  
  2.     House getHouse();  
  3. }  

再新建一个beans.xml:

 

添加如下内容:

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!-- House的一个实例bean,定义每次返回不同的实例对象 -->  
  2. <bean id="house1" class="com.mucfc.House" p:houseSize="200坪"  
  3.     p:housePosition="深南花园" p:housePrice="10万" scope="prototype" />  
  4. <!-- 实施方法注入 -->  
  5. <bean id="maginHouse" class="com.mucfc.MaginHouse">  
  6.     <lookup-method name="getHouse" bean="house1" />   
  7. </bean>  

最后来测试看看:

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1.               ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");    
  2. MaginHouse maginHouse=applicationContext.getBean("maginHouse",MaginHouse.class);  
  3. House house1=maginHouse.getHouse();  
  4. House house2=maginHouse.getHouse();  
  5. System.out.println(house1);  
  6. System.out.println(house2);  
  7. System.out.println("house2==house1?:"+(house2==house1));  
  8. HouseAgent1 houseagent1=applicationContext.getBean("houseagent1",HouseAgent1.class);  
  9. House house3=houseagent1.getHouse();  
  10. System.out.println(house3);  


输出结果:

 

通过判断我们发现house1和house2是不同的实例。深南花园要是真那么便宜就好了哇!!!

 

二、方法替换

使用一个bean里的方法去替换另一个bean里的方法。

假设原本有个房子中介HouseAgent1.java,它的定义如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.mucfc;  
  2.   
  3. public class HouseAgent1 {  
  4.     public House getHouse(){  
  5.         House house=new House();  
  6.         house.setHousePosition("松坪山村");  
  7.         house.setHouseSize("200坪");  
  8.         house.setHousePrice("4万");  
  9.         return house;  
  10.     }  
  11.   
  12. }  

 

然后我们要替换HouseAgent1.java里的getHouse()方法。这里需要再定义一个房子中介HouseAgent2.java:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.mucfc;  
  2. import java.lang.reflect.Method;  
  3. import org.springframework.beans.factory.support.MethodReplacer;  
  4. public class HouseAgent2 implements MethodReplacer{  
  5.   
  6.     @Override  
  7.     public Object reimplement(Object arg0, Method arg1, Object[] arg2)  
  8.             throws Throwable {  
  9.         House house=new House();  
  10.         house.setHousePosition("松坪山村");  
  11.         house.setHouseSize("300坪");  
  12.         house.setHousePrice("8万");  
  13.         return house;  
  14.     }  
  15. }  

然后到beans.xml增加如下代码:

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!-- 实施方法替换 -->  
  2. <bean id="houseagent1" class="com.mucfc.HouseAgent1">  
  3. <replaced-method name="getHouse" replacer="houseagent2"/>  
  4. </bean>  
  5. <bean id="houseagent2" class="com.mucfc.HouseAgent2"/>  


最后来测试看看:

 

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. //还没有进行方法替换  
  2.         HouseAgent1 houseagent1_1=new HouseAgent1();  
  3.         House house3=houseagent1_1.getHouse();  
  4.         System.out.println("-----------------HouseAgent1未进行方法替换之前-------------------");  
  5.         System.out.println(house3);  
  6.         //进行方法替换之后  
  7.         HouseAgent1 houseagent1_2=applicationContext.getBean("houseagent1",HouseAgent1.class);  
  8.         House house4=houseagent1_2.getHouse();  
  9.         System.out.println("-----------------HouseAgent1进行方法替换之后-------------------");  
  10.         System.out.println(house4);  


效果如下:

 



看到了没,我们成功的用HouseAgent2.java里的getHouse方法替换了HouseAgent1.java里的getHouse方法,是不是很神奇呢?

三、总结

Lookup方法注入干净整洁,易于扩展,更符合Ioc规则,所以尽量采用这种方式。

本文工程免费下载

分享到:
评论

相关推荐

    Ioc注入讲解

    ### Ioc注入讲解 #### 1. 容器基础 ##### 1.1 容器初探 在IoC(Inverse of Control,控制反转)框架中,容器是核心概念之一,它负责对象的管理和创建。在传统的编程模式下,对象的创建通常由程序员通过`new`...

    springioc的详细讲解

    Spring IOC,全称为Inversion of Control,即控制反转,是Spring框架的核心特性之一。它将对象的创建和管理从应用程序代码中分离出来,使得应用程序不再负责对象的生命周期,而是由Spring容器来负责。这种设计模式...

    Java IoC讲解

    IoC模式的实现之一是依赖注入(Dependency Injection),这是一种依赖关系的交付方式。在依赖注入中,对象的依赖关系是通过构造器参数、工厂方法的参数或者属性被注入到对象中,而不是由对象在运行时自行创建其依赖...

    IOC控制反转机制的讲解

    2. DI(依赖注入):是IOC的一种实现,通过容器将依赖对象注入到需要它的对象中,对象只需声明依赖,无需关心依赖的具体实现和获取方式。 理解并掌握这些概念,有助于我们构建松散耦合、易于维护和扩展的系统,特别...

    Spring IoC讲解PPT

    IoC(Inversion of Control)即控制反转,是 Spring 的核心特性之一。在传统的编程模式中,对象之间存在依赖关系,程序员需要手动创建和管理这些对象。而在 Spring 中,IoC 容器负责管理和创建对象,对象之间的依赖...

    Spring_0200_IOC_Introduction setter注入

    本篇将重点讲解Spring中的IOC,特别是setter注入的原理和使用。 **IOC原理** IOC的核心思想是将对象的创建和管理交给一个专门的容器,即Spring的IOC容器。在传统的编程中,我们通常手动创建对象并管理它们之间的...

    Spring.Net IOC依赖注入原理流程解析

    Spring.Net IOC依赖注入原理流程解析 本文将详细介绍Spring.Net IOC依赖注入原理流程解析,通过示例代码介绍了非常详细,对大家的学习或者工作具有一定的参考学习价值。 一、什么是IOC? IOC(Inversion of ...

    spring ioc和aop讲解项目demo

    本项目"spring ioc和aop讲解项目demo"旨在通过实际操作来帮助开发者深入理解这两个核心概念。 首先,让我们详细讨论一下Spring的IOC,全称Inversion of Control,即控制反转。在传统的程序设计中,对象创建和管理的...

    Spring的ioc小案例

    本案例主要探讨的是Spring框架的核心特性之一——依赖注入(Dependency Injection,简称DI),通常也被称为IOC(Inversion of Control,控制反转)。通过这个小案例,我们可以深入理解Spring如何实现IoC以及属性注入...

    自己动手实现IOC和MVC源码

    IoC,也被称为依赖注入,是一种控制反转的设计原则,它允许我们解耦组件,提高代码的可测试性和可维护性。MVC则是一种分层架构,将应用程序分为模型、视图和控制器三个部分,分别处理数据逻辑、用户界面和业务逻辑...

    Spring IOC.pdf

    Spring IOC操作的详细步骤讲解截图可能会包含以下内容: 1. 创建Spring项目,并配置项目依赖(通常是在项目的pom.xml文件中添加Spring框架的依赖)。 2. 配置Spring的IoC容器,如创建applicationContext.xml文件,并...

    Ioc(控制反转)的例子

    通过以上讲解,你应该对C#中的IoC和依赖注入有了基本的理解。在"IocInCSharp"这个压缩包中,应该包含了一些示例代码,你可以进一步研究这些代码,以便更深入地学习和实践IoC在C#中的应用。同时,不断探索不同的IoC...

    10-IoC配置-依赖注入概念(DI)

    我相信很多朋友学习IOC概念的时候,查找了很多资料结果还是一头雾水,感觉高深难懂或者一知半解,而我这篇博客就是以通俗易懂的话语,用故事的方式,讲解IOC(控制反转)和DI(依赖注入)的概念,让大家不再晕,不再觉得...

    Java反射、泛型和注解实战之Spring核心注入IOC的实现

    在本实战项目中,我们将深入探讨如何利用这些特性实现一个类似Spring框架的核心注入机制,即控制反转(Inversion of Control,简称IOC)。以下是关于这三个主题的详细讲解以及在Spring中的应用。 1. Java反射: ...

    spring_aop_ioc完全讲解

    IOC是Spring框架的核心特性之一,它将对象的创建和管理职责从应用代码转移到框架中。在传统编程中,我们需要手动创建和管理对象,而在Spring中,我们只需定义对象的配置(如类、依赖关系等),然后由Spring容器负责...

    Java反射_Spring IOC

    Spring框架的依赖注入(Dependency Injection, DI)是其核心特性之一,而Spring的IOC(Inversion of Control,控制反转)是DI的一种实现方式。在传统的编程模式中,对象通常负责自己创建所需的依赖项。而在Spring中...

    Spring中IOC和AOP的深入讲解

    Spring 中的 IOC 实现方式主要有两种:构造方法注入和 set 方法注入。构造方法注入是指在对象创建时,通过构造器注入依赖对象。set 方法注入是指通过 setter 方法将依赖对象注入到目标对象中。 依赖注入...

Global site tag (gtag.js) - Google Analytics