关于网友提出的“多线程多进程 spring 多线程bean注入”问题疑问,本网通过在网上对“多线程多进程 spring 多线程bean注入”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题:多线程多进程 spring 多线程bean注入描述:
尝试使用spring多线程开发,但是spring的注入是线程安全的,想在新开的线程中使用注入的bean,获取总是null;
代码如下:
1、线程配置
@Bean
protected ThreadPoolTaskExecutor mvcTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("my-mvc-task-executor-");
executor.setCorePoolSize(5);
executor.setMaxPoolSize(200);
return executor;
}
@Bean
protected WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setTaskExecutor(mvcTaskExecutor());
}
};
}2、spring bean获取工具类
@Configuration
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext APPLICATION_CONTEXT;
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
APPLICATION_CONTEXT = arg0;
}
/**
* 获取applicationContext对象
* @return
*/
public static ApplicationContext getApplicationContext(){
return APPLICATION_CONTEXT;
}
/**
* 根据bean的id来查找对象
* @param id
* @return
*/
public static Object getBeanById(String id){
return APPLICATION_CONTEXT.getBean(id);
}
/**
* 根据bean的class来查找对象
* @param c
* @return
*/
public static Object getBeanByClass(Class c){
return APPLICATION_CONTEXT.getBean(c);
}
/**
* 根据bean的class来查找所有的对象(包括子类)
* @param c
* @return
*/
public static Map getBeansByClass(Class c){
return APPLICATION_CONTEXT.getBeansOfType(c);
}
} 3、线程使用
@Service
public class RegisterQueueService {
private Integer num = 3;
private List producers;
@Resource
private ThreadPoolTaskExecutor mvcTaskExecutor;
public RegisterQueueService(){
producers =new ArrayList<>();
for(int i=1;i<=num;i++){
LinkedBlockingQueue blockingQueue=new LinkedBlockingQueue<>();
Producer producer =new Producer("Producer"+i, blockingQueue);
Consumer consumer =new Consumer("Consumer"+i, blockingQueue);
mvcTaskExecutor.execute(consumer);
producers.add(producer);
}
mvcTaskExecutor.shutdown();
}
public Producer getProducerByMark(String phoneNum){
int phoneLastNum = Integer.valueOf(phoneNum.substring(phoneNum.length()-1,phoneNum.length()));
Integer id =phoneLastNum%num.intValue();
return producers.get(id);
}
} 4、线程中的bean获取
public class Consumer implements Runnable {
static Logger logger = LoggerFactory.getLogger(Consumer.class);
private String producerName;
private LinkedBlockingQueue blockingQueue;
private Integer count = 0;
private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
private static SimpleDateFormat SDF_TIME = new SimpleDateFormat("HH:mm");
private HyAutoRegisterDao hyAutoRegisterDao;
private HyRuleItemDao hyRuleItemDao;
private RegisterService registerService;
private Integer T_ID = 2;
@SuppressWarnings("unchecked")
public Consumer(String name, LinkedBlockingQueue queue) {
this.producerName = name;
this.blockingQueue = queue;
this.hyAutoRegisterDao =
(HyAutoRegisterDao) SpringContextUtils.getBeanByClass(HyAutoRegisterDao.class);
this.hyRuleItemDao = (HyRuleItemDao) SpringContextUtils.getBeanByClass(HyRuleItemDao.class);
this.registerService =
(RegisterService) SpringContextUtils.getBeanByClass(RegisterService.class);
}
@Override
public void run() {
while (true) {
try {
logger.debug(producerName + ",开始处理....");
HyAutoRegister hyAutoRegister = blockingQueue.take();
excute(hyAutoRegister);
} catch (InterruptedException e) {
logger.error("线程处理出错....");
} catch (Exception e) {
logger.error("线程处理出错...." + e.getMessage());
}
count++;
}
}
...
} 经过测试,Consumer中获取的spring 的bean全是null值,注:全注解的方式写的代码
请大神看看是神马问题
解决方案1:
从来没有写过 ,不过感觉你少了@AutoWired
@Component
public class Consumer implements Runnable {
static Logger logger = LoggerFactory.getLogger(Consumer.class);
private String producerName;
private LinkedBlockingQueue blockingQueue;
private Integer count = 0;
private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
private static SimpleDateFormat SDF_TIME = new SimpleDateFormat("HH:mm");
@AutoWired
private HyAutoRegisterDao hyAutoRegisterDao;
@AutoWired
private HyRuleItemDao hyRuleItemDao;
@AutoWired
private RegisterService registerService;