Spring之@Lookup注解详细解析
作者:爱上口袋的天空
1、简介
假设一个单例的Bean A需要引用一个非单例模式的Bean B,那么在每次引用B的时候都想拿到一个新的B,该怎么做?
要知道,Bean A是单例模式的,只会被创建一次,注入一次属性,也就是说,即使B是property模式,那也是只会一个相同的B,因为A只会被注入一次。
2、解决办法
- 让bean A通过实现ApplicationContextAware来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B
- 使用Spring的Lookup注解
3、案例
原型B
@Component @Scope(value = "prototype") public class LookupTestPrototype { }
单例A
@Component public class LookupTestSingleton { @Autowired LookupTestPrototype lookupTestPrototype; public void getObjectId() { System.out.println("Singleton Object Id:" + this + ", Prototype Object Id : " + lookupTestPrototype); } }
Spock测试代码:
@ContextConfiguration( classes = [LookupTestSingleton.class, LookupTestPrototype.class] ) class Spock4SpringTest extends Specification { @Resource LookupTestSingleton singleton; def "测试单例中使用多例的注解" () { setup: for (int i = 0; i < 10; i++) { println "第"+i+"次调用的结果:" singleton.getObjectId(); } } }
Spock测试结果:
第0次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第1次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第2次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第3次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第4次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第5次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第6次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第7次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第8次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
第9次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton@b8e246c, Prototype Object Id : com.talframework.spring.LookupTestPrototype@1f387978
使用@Lookup改动的单例A代码如下:
@Component public abstract class LookupTestSingleton { @Lookup public abstract LookupTestPrototype lookupTestPrototype (); public void getObjectId() { System.out.println("Singleton Object Id:" + this + ", Prototype Object Id : " + lookupTestPrototype()); } }
调用的结果如下:
第0次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@661c46bc
第1次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@37864b77
第2次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@2b98b3bb
第3次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@540b0448
第4次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@50a691d3
第5次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@557eb543
第6次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@3b95d13c
第7次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@3730ab42
第8次调用的结果:
Singleton Object Id:com.talframework.spring.LookupTestSingleton$$EnhancerBySpringCGLIB$$15adeab8@3be4fcc0, Prototype Object Id : com.talframework.spring.LookupTestPrototype@537c8c7e
第9次调用的结果:
需要注意的是@Lookup只能注解在方法上,这个时候可以注解在一个抽象方法上。
到此这篇关于Spring之@Lookup注解详细解析的文章就介绍到这了,更多相关@Lookup注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!