多线程多进程 spring 多线程bean注入

来源:互联网  时间:2016/6/28 0:38:53

关于网友提出的“多线程多进程 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;

上一篇求解决Tomcat报错This is very likely to create a memory leak问题?
下一篇Struts2 新手的问题
明星图片
相关文章
《多线程多进程 spring 多线程bean注入》由码蚁之家搜集整理于网络,
联系邮箱:mxgf168#qq.com(#改为@)