Spring singleton bean 与 prototype bean 的依赖

简介:

问题

我们知道,Spring bean 默认的 scope 是 singleton(单例),但有些场景(比如多线程)需要每次调用都生成一个实例, 此时 scope 就应该设为 prototype。如:

@Component @Scope("prototype")
public class DadTask implements Runnable {
 static Logger logger = Logger.getLogger(DadTask.class);

 @Autowired
 DadDao dadDao;

 private String name;
 /**
 * 
 */ public DadTask setDadTask(String name) {
 this.name = name;
 return this;
 }

 /* (non-Javadoc)
 * @see java.lang.Runnable#run()
 */ @Override public void run() {
 logger.info("DadTask:"+this + ";DadDao:"+dadDao + ";"+dadDao.sayHello(name) );
 //logger.info("Dad:"+name);
 }

}

但是,如果 singlton bean 依赖 prototype bean ,通过依赖注入方式, prototype bean 在 singlton bean 实例化时会创建一次(只一次), 比如:

@Service public class UserService {

 @Autowired private DadTask dadTask;

 public void startTask() {
 ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2);

 scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lily"), 1000, 2000, TimeUnit.MILLISECONDS);
 scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lucy"), 1000, 2000, TimeUnit.MILLISECONDS);
 }
}

我希望调度“Lily” 和 “Lucy” 两个线程,实际上,它只给我初始化一个实例(这样就线程非安全了)。

解决

如果 singlton bean 想每次都去创建一个新的 prototype bean 的实例, 需要通过方法注入的方式。 可以通过实现 ApplicationContextAware 接口,来获取到 ApplicationContext 实例, 继而通过 getBean 方法来获取到 prototype bean 的实例。我们的程序需要修改如下:

@Service public class UserService implements ApplicationContextAware {

 @Autowired private DadTask dadTask;

 private ApplicationContext applicationContext;

 public void startTask() {
 ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2);

 // 每次都拿到 DadTask 的实例
 dadTask = applicationContext.getBean("dadTask", DadTask.class);
 scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lily"), 1000, 2000, TimeUnit.MILLISECONDS);
 dadTask = applicationContext.getBean("dadTask", DadTask.class);
 scheduledThreadPoolExecutor.scheduleAtFixedRate(dadTask.setDadTask("Lucy"), 1000, 2000, TimeUnit.MILLISECONDS);
 }

 @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException {
 this.applicationContext = applicationContext;

 }
}

OK ,问题解决

源码

https://github.com/waylau/spring-framework-4-demosbeanScope 目录

参考

目录
相关文章
|
8月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
528 26
|
7月前
|
Java Maven 微服务
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的 maven 依赖
在项目中使用Swagger2工具时,需导入Maven依赖。尽管官方最高版本为2.8.0,但其展示效果不够理想且稳定性欠佳。实际开发中常用2.2.2版本,因其稳定且界面友好。以下是围绕2.2.2版本的Maven依赖配置,包括`springfox-swagger2`和`springfox-swagger-ui`两个模块。
225 0
|
7月前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th="http://www.thymeleaf.org"`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
290 0
|
10月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
188 12
|
10月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
238 12
|
10月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
269 6
|
10月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
433 4
|
Java 关系型数据库 MySQL
06_spring_ 依赖注入| 学习笔记
快速学习 06_spring_ 依赖注入
140 0
|
3月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
759 0
|
7月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
331 0