关于网友提出的“多线程多进程 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 List4、线程中的bean获取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); } }
public class Consumer implements Runnable { static Logger logger = LoggerFactory.getLogger(Consumer.class); private String producerName; private LinkedBlockingQueueblockingQueue; 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 LinkedBlockingQueueblockingQueue; 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;