spring prototype 使用场景

在 Spring IoC 容器中具有以下几种作用域:

  • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例,适用于无状态bean;
  • prototype:原型模式,`每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例,适用于有状态的Bean; ----

demo

环境搭建

定义@Scope(“prototype”)- bean

@Slf4j
@Component
@Scope("prototype")
public class FooService {
    @Value("${x.foo}")
    private String foo;

    public void foo() {
        log.info("---foo:{} ,{}", foo, this);
    }

    @PostConstruct
    public void init() {
        log.info("---foo:init");
    }

    public FooService(){
        log.info("---foo:construct");
    }
    
	@PreDestroy
    public void destroy(){
        log.warn("---foo:destroy");
    }
}

@Slf4j
@Component
@Scope("prototype")
public class BarService {

    @Value("${x.bar}")
    private String bar;

    public void bar() {
        log.info("---bar:{} ,{}",bar,this);
    }


    @PostConstruct
    public void init() {
        log.info("---bar:init");
    }

    public BarService(){
        log.info("---bar:construct");
    }
	
    @PreDestroy
    public void destroy(){
        log.warn("---bar:destroy");
    }
}
定义@Scope(“singleton”)-bean
@Component
@Scope("singleton")
//@Lazy
@Slf4j
public class SingletonService {

    public void exec() {
        log.info("---singleton:{} ",  this);
    }

    @PostConstruct
    public void init() {
        log.info("---singleton:init");
    }

    public SingletonService(){
        log.info("---singleton:construct");
    }

    @PreDestroy
    public void destroy(){
        log.warn("---singleton:destroy");
    }
}
定义bean调用者
@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private FooService fooService;

    @Autowired
    private ApplicationContext applicationContext;

    @GetMapping("/refresh")
    public String refresh(){
    	log.info("-------------------------------");
        applicationContext.getBean(BarService.class).bar();
        fooService.foo();
		applicationContext.getBean(SingletonService.class).exec();
        return "success";
    }
	
	@GetMapping("/shutdown")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) applicationContext).close();
    }
}

日志

启动服务时
2022-09-28 13:56:02.035 [main] INFO  c.j.e.e.refresh2.service.FooService - ---foo:construct
2022-09-28 13:56:02.038 [main] INFO  c.j.e.e.refresh2.service.FooService - ---foo:init
2022-09-28 13:56:02.042 [main] INFO  c.j.e.e.r.service.SingletonService - ---singleton:construct
2022-09-28 13:56:02.042 [main] INFO  c.j.e.e.r.service.SingletonService - ---singleton:init
  • FooService: 虽然scope为"prototype",但是由@Autowired自动注入,所以在启动容器时就已经通过getBean()被注入。
  • SingletonService: scope为"singleton",启动时便被注入
    • 可以通过: @Lazy 来控制是否在容器启动时就初始化。

执行"/refresh"请求

  • BarService:在执行请求后,方才执行getBean()方法,此时BarService才初始化。 — 延迟初始化
2022-09-28 13:56:39.693 [http-nio-8080-exec-1] INFO  c.j.e.e.refresh2.TestController - -------------------------------
2022-09-28 13:56:39.694 [http-nio-8080-exec-1] INFO  c.j.e.e.refresh2.service.BarService - ---bar:construct
2022-09-28 13:56:39.695 [http-nio-8080-exec-1] INFO  c.j.e.e.refresh2.service.BarService - ---bar:init
2022-09-28 13:56:39.695 [http-nio-8080-exec-1] INFO  c.j.e.e.refresh2.service.BarService - ---bar:BAR4 ,cn.jhs.e2e.e2eencryptionbiz.refresh2.service.BarService@4cfd6769
2022-09-28 13:56:39.697 [http-nio-8080-exec-1] INFO  c.j.e.e.refresh2.service.FooService - ---foo:FOO4 ,cn.jhs.e2e.e2eencryptionbiz.refresh2.service.FooService@2f51409b
2022-09-28 13:56:39.697 [http-nio-8080-exec-1] INFO  c.j.e.e.r.service.SingletonService - ---singleton:cn.jhs.e2e.e2eencryptionbiz.refresh2.service.SingletonService@60aec68a 

再次执行"/refresh"请求

  • BarService:在执行第二次请求后,由spring再次初始化,返回一个新的实例.
2022-09-28 13:57:35.822 [http-nio-8080-exec-2] INFO  c.j.e.e.refresh2.TestController - -------------------------------
2022-09-28 13:57:35.823 [http-nio-8080-exec-2] INFO  c.j.e.e.refresh2.service.BarService - ---bar:construct
2022-09-28 13:57:35.823 [http-nio-8080-exec-2] INFO  c.j.e.e.refresh2.service.BarService - ---bar:init
2022-09-28 13:57:35.823 [http-nio-8080-exec-2] INFO  c.j.e.e.refresh2.service.BarService - ---bar:BAR4 ,cn.jhs.e2e.e2eencryptionbiz.refresh2.service.BarService@71f187fc
2022-09-28 13:57:35.823 [http-nio-8080-exec-2] INFO  c.j.e.e.refresh2.service.FooService - ---foo:FOO4 ,cn.jhs.e2e.e2eencryptionbiz.refresh2.service.FooService@2f51409b
2022-09-28 13:57:35.823 [http-nio-8080-exec-2] INFO  c.j.e.e.r.service.SingletonService - ---singleton:cn.jhs.e2e.e2eencryptionbiz.refresh2.service.SingletonService@60aec68a 
执行"/shutdown"

只有@Scope("singleton")bean ,会执行destory()方法.
2022-09-28 13:59:31.973 [http-nio-8080-exec-4] WARN c.j.e.e.r.service.SingletonService - —singleton:destroy

结论

Spring

  • 不对作用域为prototype的bean的整个生命周期负责:容器在bean初始化&实例后,不再负责bean的销毁。
  • 作用域为singleton的bean的整个生命周期负责
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值