• 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的整个生命周期负责
  • 相关阅读:
    java基于ssm+vue+elementui的疫情期间医院就诊管理 前后端分离
    【机器学习笔记15】多分类混淆矩阵、F1-score指标详解与代码实现(含数据)
    C语言概念知识扫盲(不定期补充更新)
    35道最新【软件测试】面试题,常见面试题及答案汇总
    记一次nginx负载均衡健康检查引起的事故之no live upstreams while connecting to upstream
    最高月薪17K,每一个成功者都有一个开始。勇于开始,才能找到成功的路~
    HIS -- 医院信息管理系统业务流程
    iPhone苹果手机iOS18如何隐藏打开APP怎么找出来恢复隐藏APP?
    Air780E模块休眠控制应用指南
    maven遇到的所遇到的问题及解决办法
  • 原文地址:https://blog.csdn.net/it_freshman/article/details/127087739