IOC之方法注入讲解
2015-10-02 18:13
453 查看
方法注入在我看来就是为了实现在单例类中取得不同的实例类对象。
当一个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方法注射指容器能够重写容器中bean的抽象或具体方法,返回查找容器中其他bean的结果。 被查找的bean在上面描述的场景中通常是一个non-singleton bean (尽管也可以是一个singleton的)。Spring通过使用CGLIB库在客户端的类之上修改二进制码, 从而实现上述的场景要求。
理解:“Lookup方法”可以使Spring替换一个bean原有的,获取其它对象具体的方法,并自动返回在容器中的查找结果。
下面来看看个例子吧。
定义一个House.java:
[java] view
plaincopy
package com.mucfc;
public class House {
private String houseSize;
private String housePosition;
private String housePrice;
public String getHouseSize() {
return houseSize;
}
public void setHouseSize(String houseSize) {
this.houseSize = houseSize;
}
public String getHousePosition() {
return housePosition;
}
public void setHousePosition(String housePosition) {
this.housePosition = housePosition;
}
public String getHousePrice() {
return housePrice;
}
public void setHousePrice(String housePrice) {
this.housePrice = housePrice;
}
public String toString(){
return "房子大小:"+houseSize+" 房子位置:"+housePosition+" 房子价格:"+housePrice;
}
}
然后定义一个每次都获得一个house对象的类MaginHouse.java,
[java] view
plaincopy
public interface MaginHouse {
House getHouse();
}
再新建一个beans.xml:
添加如下内容:
[html] view
plaincopy
<!-- House的一个实例bean,定义每次返回不同的实例对象 -->
<bean id="house1" class="com.mucfc.House" p:houseSize="200坪"
p:housePosition="深南花园" p:housePrice="10万" scope="prototype" />
<!-- 实施方法注入 -->
<bean id="maginHouse" class="com.mucfc.MaginHouse">
<lookup-method name="getHouse" bean="house1" />
</bean>
最后来测试看看:
[java] view
plaincopy
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
MaginHouse maginHouse=applicationContext.getBean("maginHouse",MaginHouse.class);
House house1=maginHouse.getHouse();
House house2=maginHouse.getHouse();
System.out.println(house1);
System.out.println(house2);
System.out.println("house2==house1?:"+(house2==house1));
HouseAgent1 houseagent1=applicationContext.getBean("houseagent1",HouseAgent1.class);
House house3=houseagent1.getHouse();
System.out.println(house3);
输出结果:
通过判断我们发现house1和house2是不同的实例。深南花园要是真那么便宜就好了哇!!!
使用一个bean里的方法去替换另一个bean里的方法。
假设原本有个房子中介HouseAgent1.java,它的定义如下:
[java] view
plaincopy
package com.mucfc;
public class HouseAgent1 {
public House getHouse(){
House house=new House();
house.setHousePosition("松坪山村");
house.setHouseSize("200坪");
house.setHousePrice("4万");
return house;
}
}
然后我们要替换HouseAgent1.java里的getHouse()方法。这里需要再定义一个房子中介HouseAgent2.java:
[java] view
plaincopy
package com.mucfc;
import java.lang.reflect.Method;
import org.springframework.beans.factory.support.MethodReplacer;
public class HouseAgent2 implements MethodReplacer{
@Override
public Object reimplement(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
House house=new House();
house.setHousePosition("松坪山村");
house.setHouseSize("300坪");
house.setHousePrice("8万");
return house;
}
}
然后到beans.xml增加如下代码:
[html] view
plaincopy
<!-- 实施方法替换 -->
<bean id="houseagent1" class="com.mucfc.HouseAgent1">
<replaced-method name="getHouse" replacer="houseagent2"/>
</bean>
<bean id="houseagent2" class="com.mucfc.HouseAgent2"/>
最后来测试看看:
[java] view
plaincopy
//还没有进行方法替换
HouseAgent1 houseagent1_1=new HouseAgent1();
House house3=houseagent1_1.getHouse();
System.out.println("-----------------HouseAgent1未进行方法替换之前-------------------");
System.out.println(house3);
//进行方法替换之后
HouseAgent1 houseagent1_2=applicationContext.getBean("houseagent1",HouseAgent1.class);
House house4=houseagent1_2.getHouse();
System.out.println("-----------------HouseAgent1进行方法替换之后-------------------");
System.out.println(house4);
效果如下:
看到了没,我们成功的用HouseAgent2.java里的getHouse方法替换了HouseAgent1.java里的getHouse方法,是不是很神奇呢?
Lookup方法注入干净整洁,易于扩展,更符合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
package com.mucfc;
public class House {
private String houseSize;
private String housePosition;
private String housePrice;
public String getHouseSize() {
return houseSize;
}
public void setHouseSize(String houseSize) {
this.houseSize = houseSize;
}
public String getHousePosition() {
return housePosition;
}
public void setHousePosition(String housePosition) {
this.housePosition = housePosition;
}
public String getHousePrice() {
return housePrice;
}
public void setHousePrice(String housePrice) {
this.housePrice = housePrice;
}
public String toString(){
return "房子大小:"+houseSize+" 房子位置:"+housePosition+" 房子价格:"+housePrice;
}
}
然后定义一个每次都获得一个house对象的类MaginHouse.java,
[java] view
plaincopy
public interface MaginHouse {
House getHouse();
}
再新建一个beans.xml:
添加如下内容:
[html] view
plaincopy
<!-- House的一个实例bean,定义每次返回不同的实例对象 -->
<bean id="house1" class="com.mucfc.House" p:houseSize="200坪"
p:housePosition="深南花园" p:housePrice="10万" scope="prototype" />
<!-- 实施方法注入 -->
<bean id="maginHouse" class="com.mucfc.MaginHouse">
<lookup-method name="getHouse" bean="house1" />
</bean>
最后来测试看看:
[java] view
plaincopy
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
MaginHouse maginHouse=applicationContext.getBean("maginHouse",MaginHouse.class);
House house1=maginHouse.getHouse();
House house2=maginHouse.getHouse();
System.out.println(house1);
System.out.println(house2);
System.out.println("house2==house1?:"+(house2==house1));
HouseAgent1 houseagent1=applicationContext.getBean("houseagent1",HouseAgent1.class);
House house3=houseagent1.getHouse();
System.out.println(house3);
输出结果:
通过判断我们发现house1和house2是不同的实例。深南花园要是真那么便宜就好了哇!!!
二、方法替换
使用一个bean里的方法去替换另一个bean里的方法。假设原本有个房子中介HouseAgent1.java,它的定义如下:
[java] view
plaincopy
package com.mucfc;
public class HouseAgent1 {
public House getHouse(){
House house=new House();
house.setHousePosition("松坪山村");
house.setHouseSize("200坪");
house.setHousePrice("4万");
return house;
}
}
然后我们要替换HouseAgent1.java里的getHouse()方法。这里需要再定义一个房子中介HouseAgent2.java:
[java] view
plaincopy
package com.mucfc;
import java.lang.reflect.Method;
import org.springframework.beans.factory.support.MethodReplacer;
public class HouseAgent2 implements MethodReplacer{
@Override
public Object reimplement(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
House house=new House();
house.setHousePosition("松坪山村");
house.setHouseSize("300坪");
house.setHousePrice("8万");
return house;
}
}
然后到beans.xml增加如下代码:
[html] view
plaincopy
<!-- 实施方法替换 -->
<bean id="houseagent1" class="com.mucfc.HouseAgent1">
<replaced-method name="getHouse" replacer="houseagent2"/>
</bean>
<bean id="houseagent2" class="com.mucfc.HouseAgent2"/>
最后来测试看看:
[java] view
plaincopy
//还没有进行方法替换
HouseAgent1 houseagent1_1=new HouseAgent1();
House house3=houseagent1_1.getHouse();
System.out.println("-----------------HouseAgent1未进行方法替换之前-------------------");
System.out.println(house3);
//进行方法替换之后
HouseAgent1 houseagent1_2=applicationContext.getBean("houseagent1",HouseAgent1.class);
House house4=houseagent1_2.getHouse();
System.out.println("-----------------HouseAgent1进行方法替换之后-------------------");
System.out.println(house4);
效果如下:
看到了没,我们成功的用HouseAgent2.java里的getHouse方法替换了HouseAgent1.java里的getHouse方法,是不是很神奇呢?
三、总结
Lookup方法注入干净整洁,易于扩展,更符合Ioc规则,所以尽量采用这种方式。本文工程免费下载
林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
相关文章推荐
- 求集合并集
- IOC之基于注解的配置bean(上)
- Spring之核心容器bean
- Long类
- 任意区间的最长连续递增子序列,最大连续子序列和
- 解决VS 于 致命错误 RC1015: 无法打开包含文件 'afxres.h' 问题
- Spring之Construcotrer注入和setter注入不同的XML写法方式
- [No00000B]MS OFFICE 2013 快捷键大全
- Android 面试题目
- 11.29_常见对象(Object类的equals()方法代码优化).avi
- HTML常用标签
- Spring之IOC自动装配解析
- 一起talk C栗子吧(第五十一回:C语言实例--最小生成树三)
- mac mysql 插入中文乱码
- 11.28_常见对象(Object类的equals()方法).avi
- 在什么情况下应当声明虚函数
- Spring之IOC的注入方式总结
- C++内联函数(内嵌函数,内置函数)
- C++虚析构函数详解
- Android 矢量图(VectorDrawable)及动画(AnimatedVectorDrawable)