• 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的整个生命周期负责
  • 相关阅读:
    VS2017/2019均适用的opencv 快速通用免重复安装配置流程
    【ARFoundation学习笔记】点云与参考点
    第15章_锁: MySQL并发访问相同记录以及从数据操作的类型划分锁(读锁、写锁)
    如何用蓝牙实现无线定位(一)--系统原理
    尖端AR技术如何在美国革新外科手术实践?
    Java关键字super解释
    亚马逊云科技出海日6月9日盛夏盛启
    前端基建——前端团队技术构建方向指引
    【华为OD机试python】报数游戏【2023 B卷|100分】
    不同python包下的逻辑回归问题
  • 原文地址:https://blog.csdn.net/it_freshman/article/details/127087739