07-Bean的作用域

我们用的最多的就是单例singleton了,这个就不再描述

prototype

原型,即我们讲的多例。spring用的属性是注入的方式,即时定义bean的作用域为原型,属性的引用也不会变,也就达不到想要的多例效果。那么怎样才是使用原型的正确方式呢?

准备Bean

@Component
@Scope("prototype")
public class F1 {
}

@Component
@Scope("prototype")
public class F2 {

}

@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class F3 {

}

@Component
@Scope("prototype")
public class F4 {


}

使用多例

@Getter
@Component
public class E {

    @Autowired
    private F1 f1;

    @Lazy
    @Autowired
    private F2 f2;

    @Autowired
    private F3 f3;

    @Autowired
    private ObjectFactory<F4> f4;

    @Autowired
    private ApplicationContext applicationContext;

    public F1 getF12() {
        return applicationContext.getBean(F1.class);
    }

    public F4 getF4() {
        return f4.getObject();
    }

}

验证

ConfigurableApplicationContext applicationContext = SpringApplication.run(TestScope02.class, args);
E e = applicationContext.getBean(E.class);
System.out.println("==========F1========");
for (int i = 0; i < 3; i++) {
    // F1对象都是同一个   多例无效果
    System.out.println(e.getF1());
}
System.out.println("==========F1========");


System.out.println("==========F2========");
for (int i = 0; i < 3; i++) {
    // @Lazy   F2对象都不相同  多例生效
    System.out.println(e.getF2());
}
System.out.println("==========F2========");

System.out.println("==========F3========");
for (int i = 0; i < 3; i++) {
    // proxyMode = ScopedProxyMode.TARGET_CLASS F3对象都不相同  多例生效
    System.out.println(e.getF3());
}
System.out.println("==========F3========");


System.out.println("==========F4========");
for (int i = 0; i < 3; i++) {
    // ObjectFactory 对象都不相同  多例生效
    System.out.println(e.getF4());
}
System.out.println("==========F4========");

System.out.println("==========F12========");
for (int i = 0; i < 3; i++) {
    // ApplicationContext 对象都不相同  多例生效
    System.out.println(e.getF12());
}
System.out.println("==========F12========");

applicationContext.close();

request、session、application

准备bean

@Scope("request")
@Component
public class Bean4Request {

    @PreDestroy
    public void destroy() {
        // request请求结束立即销毁
        System.err.println("Bean4Request destroy");
    }

}

@Scope("session")
@Component
public class Bean4Session {

    @PreDestroy
    public void destroy() {
        System.err.println("Bean4Session destroy");
    }

}

@Scope("application")
@Component
public class Bean4Application {

    @PreDestroy
    public void destroy() {
        System.err.println("Bean4Application destroy");
    }

}

验证

@RestController
public class TestController {
    /**
     * 单例Bean引入非单例Bean需要添加@Lazy注解(还有其它方式)
     * 否则引入的对象仍表现为单例
     */

    @Lazy
    @Autowired
    private Bean4Request bean4Request;

    @Lazy
    @Autowired
    private Bean4Session bean4Session;

    @Lazy
    @Autowired
    private Bean4Application bean4Application;

    @GetMapping(value = "/test")
    public String test() {
        return "<ul>" +
                "<li> request scope:" + bean4Request + "</li>" +
                "<li> session scope:" + bean4Session + "</li>" +
                "<li> application scope:" + bean4Application + "</li>" +
                "</ul>";
    }

}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

层巅余落日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值