Spring 单例注入其它 scope 的四种解决方法 &@Scope 源码解读

@Scope 注解源码解读

当与@Component一起用作类型级别的注解时,@ @Scope指示用于注解类型实例的范围名称。
当与@Bean一起用作方法级别的注释时, @Scope指示用于从方法返回的实例的范围名称

 属性:value() & scopeName()

singleton、prototype、servletContext、application、session、request

属性:proxyMode

DEFAULT、NO、INTERFACES、TARGET_CLASS

 

@Scope的缺省属性

scopeName() default "" 默认为空字符串 ( "" ),这意味着SCOPE_SINGLETON 
proxyMode() default ScopedProxyMode.DEFAULT;

 

单例注入其它 scope 的四种解决方法

  • @Lazy

  • @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)

  • ObjectFactory

  • ApplicationContext

  1. 解决方法虽然不同,但理念上殊途同归: 都是推迟其它 scope bean 的获取

代码演示

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
package com.jay;

@Scope("prototype")
@Component
public class F1 {
}
package com.jay;

@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Component
public class F2 {
}
package com.jay;

@Scope("prototype")
@Component
public class F3 {
}
package com.jay;

@Scope("prototype")
@Component
public class F4 {
}
package com.jay;

@Component
public class E {

    @Lazy
    @Autowired
    private F1 f1;

    @Autowired
    private F2 f2;

    @Autowired
    private ObjectFactory<F3> f3;

    @Autowired
    private ApplicationContext context;

    public F1 getF1() {
        return f1;
    }

    public F2 getF2() {
        return f2;
    }

    public F3 getF3() {
        return f3.getObject();
    }

    public F4 getF4() {
        return context.getBean(F4.class);
    }
}
@ComponentScan("com.jay") // 所有@Component 所在的位置
public class A08_1 {

    private static final Logger log = LoggerFactory.getLogger(A08_1.class);

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(A08_1.class);

        E e = context.getBean(E.class);
        log.debug("{}", e.getF1().getClass());
        log.debug("{}", e.getF1());
        log.debug("{}", e.getF1());
        log.debug("{}", e.getF1());

        log.debug("{}", e.getF2().getClass());
        log.debug("{}", e.getF2());
        log.debug("{}", e.getF2());
        log.debug("{}", e.getF2());

        log.debug("{}", e.getF3());
        log.debug("{}", e.getF3());

        log.debug("{}", e.getF4());
        log.debug("{}", e.getF4());

        context.close();
        /*
            学到了什么
                a. 单例注入其它 scope 的四种解决方法
                b. 解决方法虽然不同, 但理念上殊途同归: 都是推迟其它 scope bean 的获取
         */
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值