Spring之不同步的Bean
2016-02-28 23:42
477 查看
singleton作用域的Bean只有一次初始化的机会,它的依赖关系也只有在初始化阶段被设置,当singleton作用域的Bean依赖prototype作用域的Bean时,Spring容器会在初始化singleton作用域的Bean之前,先创建被依赖的prototype Bean,然后才初始化singleton Bean,并将prototype Bean注入singleton Bean,这会导致以后无论何时通过singleton Bean去访问prototype Bean时,得到的永远是最初那个prototype
Bean——这样就相当于singleton Bean把所依赖的prototype Bean变成了singleton行为。
![](http://img.blog.csdn.net/20160228234222838?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
为了解决这样的问题,我们利用方法注入,方法注入通常使用lookup方法注入,使用lookup方法注入可以让Spring容器重写容器中Bean的抽象或具体方法,返回查找容器中其他Bean的结果,被查找的Bean通常是一个non-singleton Bean(尽管也可以是一个singleton的)。Spring通过使用JSK动态代理或cglib库修改客户的二进制码,从而实现上述要求。下面我们来看一个例子。
1) 将调用者Bean的实现类定义为抽象类,并定义一个抽象方法来获取被依赖的Bean.
2) 在<bean../>元素中添加<lookup-method../>子元素让Spring为调用者Bean的实现类实现指定的抽象方法。Spring为抽象方法提供实现体之后,这个方法就会变成具体方法,这个类也就变成了具体类,拉下来Spring就可以创建该Bean的实例。<lookup-method../>元素需要指定如下两个属性。
Ø name:指定需要让Spring实现的方法
Ø bean:指定Spring实现该方法的返回值
3) 下面定一个测试类。
4) 测试结果。
true
我带着:com.owen.app.service.impl.GunDog@4b553d26出去打猎
我是一只叫旺财的猎犬,奔跑迅速…
我带着:com.owen.app.service.impl.GunDog@69a3d1d出去打猎
我是一只叫旺财的猎犬,奔跑迅速…
Bean——这样就相当于singleton Bean把所依赖的prototype Bean变成了singleton行为。
为了解决这样的问题,我们利用方法注入,方法注入通常使用lookup方法注入,使用lookup方法注入可以让Spring容器重写容器中Bean的抽象或具体方法,返回查找容器中其他Bean的结果,被查找的Bean通常是一个non-singleton Bean(尽管也可以是一个singleton的)。Spring通过使用JSK动态代理或cglib库修改客户的二进制码,从而实现上述要求。下面我们来看一个例子。
1) 将调用者Bean的实现类定义为抽象类,并定义一个抽象方法来获取被依赖的Bean.
public abstract class Chinese implements Person { private Dog dog; // 定义抽象方法,该方法用于获取被依赖Bean public abstract Dog getDog(); public void hunt() { System.out.println("我带着:" + getDog() + "出去打猎"); System.out.println(getDog().run()); } }
2) 在<bean../>元素中添加<lookup-method../>子元素让Spring为调用者Bean的实现类实现指定的抽象方法。Spring为抽象方法提供实现体之后,这个方法就会变成具体方法,这个类也就变成了具体类,拉下来Spring就可以创建该Bean的实例。<lookup-method../>元素需要指定如下两个属性。
Ø name:指定需要让Spring实现的方法
Ø bean:指定Spring实现该方法的返回值
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="chinese" class="com.owen.app.service.impl.Chinese"> <!-- Spring只要检测到lookup-method元素, Spring会自动为该元素的name属性所指定的方法提供实现体。--> <lookup-method name="getDog" bean="gunDog"/> </bean> <!-- 指定gunDog Bean的作用域为prototype, 希望程序每次使用该Bean时用到的总是不同的实例 --> <bean id="gunDog" class="com.owen.app.service.impl.GunDog" scope="prototype"> <property name="name" value="旺财"/> </bean> </beans>
3) 下面定一个测试类。
public class SpringTest { public static void main(String[] args) { // 以类加载路径下的beans.xml作为配置文件,创建Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Person p1 = ctx.getBean("chinese" , Person.class); Person p2 = ctx.getBean("chinese" , Person.class); // 由于chinese Bean是singleton行为, // 因此程序两次获取的chinese Bean是同一个实例。 System.out.println(p1 == p2); p1.hunt(); p2.hunt(); } }
4) 测试结果。
true
我带着:com.owen.app.service.impl.GunDog@4b553d26出去打猎
我是一只叫旺财的猎犬,奔跑迅速…
我带着:com.owen.app.service.impl.GunDog@69a3d1d出去打猎
我是一只叫旺财的猎犬,奔跑迅速…
相关文章推荐
- javaweb jsp页面上传excel文件
- JAVA设计模式之单例模式
- Spring之获得Bean本身的id
- MyEclipse激活教程
- Spring之容中的工厂Bean
- java EE解决中文乱码问题
- java获取文件
- java-tip-各种Map的区别及如何选择
- Java设计模式之适配器模式(Adapter)
- 【JAVA】23、方法的递归调用
- java的集合框架最全详解
- java 接口
- Java中只有按值传递,没有按引用传递!
- SpringMVC静态资源无法访问的一个奇怪的问题
- jrebel实现Java热更不用真是暴殄天物
- Java IO和NIO
- Java中数字格式化问题
- java学习(一)——环境的搭建与“Hellow World!”
- Java反射机制的几点用法
- Java的Calendar使用