spring之@Lookup注解

目录

1、简介

2、解决办法 

3、案例 


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源码学习,spring)