SpringBoot启动时启动独立线程无法读取properties配置文件属性问题
问题根因
- 你在
CommandLineRunner的实现中通过new CsvReader()手动创建了类实例,这个实例没有被Spring IoC容器托管,Spring不会对非容器管理的对象执行@Value属性注入、自动装配等操作,因此appUrl属性为null。 - 虽然你给
CsvReader加了@Component注解,但是你没有使用Spring容器提供的实例,而是自行创建了新的实例,注解对应的注入逻辑没有生效。
可行解决方案
方案1:直接注入容器托管的CsvReader实例(首选)
CsvReader已经标注了@Component,Spring启动时会自动生成托管的单例实例,直接注入使用即可保证@Value属性正常注入,修改Application类的schedulingRunner方法代码如下:
@Bean public CommandLineRunner schedulingRunner(TaskExecutor executor, CsvReader csvReader) { return args -> executor.execute(csvReader); }
方案2:需要每次新建CsvReader实例的场景
如果业务要求每次执行都新建实例,不要复用单例,可以按如下步骤修改:
- 给
CsvReader添加多例注解
@Component @Scope("prototype") public class CsvReader implements Runnable{ // 原有代码保持不变 }
- 注入ApplicationContext,从容器中获取实例
@Bean public CommandLineRunner schedulingRunner(TaskExecutor executor, ApplicationContext context) { return args -> executor.execute(context.getBean(CsvReader.class)); }
通过容器获取的多例实例,依然会被Spring执行属性注入,能正常读取@Value对应的配置值。
方案3:手动传值(不推荐)
如果非要自行创建CsvReader实例,可以把配置值手动传入构造方法:
- 修改
CsvReader增加带参数的构造方法
@Component public class CsvReader implements Runnable{ private String appUrl; public CsvReader(@Value("${file-url}") String appUrl) { this.appUrl = appUrl; } @Override public void run() { System.out.println("run after Object created: "+ appUrl); } }
- 注入配置值后传入新实例
@Bean public CommandLineRunner schedulingRunner(TaskExecutor executor, @Value("${file-url}") String appUrl) { return args -> executor.execute(new CsvReader(appUrl)); }
内容的提问来源于stack exchange,提问作者Saurabh Jhunjhunwala
相关产品推荐
相关产品推荐

