近期,在项目中需要用到多线程,而且需要读取配置文件中RocketMq的相关参数,于是乎自自然而然的将配置文件映射到实体类中(据说Spring不建议这样干?),重复三遍,以后具体查一下:
为什么Spring不建议将配置映射到实体类?
为什么Spring不建议将配置映射到实体类?
为什么Spring不建议将配置映射到实体类?
然后,自然而然的用@Autowired在多线程中注入这个实体类!就这样奇迹发生了…
在多线程中注入的实体类一直 空指针异常,而在test中却完全没问题,说明我的映射是成功了的,那,为啥?
经过一番与度娘的激烈讨论,原来如此:
在线程中为了安全,是防注入的
那,这岂不是很坑,不过为了安全,我忍了!
复盘一下我们的应用场景
假设application.properties中是这样的(yml文件同理):
user.name=aran
user.sex=male
user.age=18
user.job=coder
通过实体类进行配置文件映射:
package com.aran.test.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "user")
public class PropConfig {
private String name;
private String sex;
private String age;
private String job;
@Override
public String toString() {
return "PropConfig [name=" + name + ", sex=" + sex + ", age=" + age + ", job=" + job + "]";
}
}
简单写一个线程类:
package threads;
import org.springframework.beans.factory.annotation.Autowired;
import com.aran.test.config.PropConfig;
public class TestThreads implements Runnable{
@Autowired
PropConfig propConfig;
@Override
public void run() {
System.out.println("进入线程" + Thread.currentThread().getName());
System.out.println("==================开始读取参数========================");
System.out.println(propConfig.getName());
System.out.println(propConfig.getAge());
System.out.println("=======================参数读取完毕===================");
}
}
为了方便,我就直接在主类中启动一个线程:
package com.aran.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import threads