首页 / 博客文章 / 多线程(Runnable)类或者是监听器中获取不到@Autowired注入bean对象解决办法

Java

多线程(Runnable)类或者是监听器中获取不到@Autowired注入bean对象解决办法

Java实例  云邦 2022-07-28 15:07:00 458 0条

原因分析

在多线程时使用@Autowired总是获取不到bean,原因是:new thread不在spring容器中,也就无法获得spring中的bean对象。

解决办法

手动获取,新建一个工具类,代码如下

  1. package com.gdie.modules.oplog.util;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.ApplicationContextAware;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * 解决多线程处理任务时无法通过@Autowired注入bean
  8. */
  9. @Component
  10. public class ApplicationContextProvider implements ApplicationContextAware {
  11. /**
  12. * 上下文对象实例
  13. */
  14. private static ApplicationContext applicationContext;
  15. @Override
  16. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  17. this.applicationContext = applicationContext;
  18. }
  19. /**
  20. * 获取applicationContext
  21. *
  22. * @return
  23. */
  24. public static ApplicationContext getApplicationContext() {
  25. return applicationContext;
  26. }
  27. /**
  28. * 通过name获取 Bean.
  29. *
  30. * @param name
  31. * @return
  32. */
  33. public static Object getBean(String name) {
  34. return getApplicationContext().getBean(name);
  35. }
  36. /**
  37. * 通过class获取Bean.
  38. *
  39. * @param clazz
  40. * @param <T>
  41. * @return
  42. */
  43. public static <T> T getBean(Class<T> clazz) {
  44. return getApplicationContext().getBean(clazz);
  45. }
  46. /**
  47. * 通过name,以及Clazz返回指定的Bean
  48. *
  49. * @param name
  50. * @param clazz
  51. * @param <T>
  52. * @return
  53. */
  54. public static <T> T getBean(String name, Class<T> clazz) {
  55. return getApplicationContext().getBean(name, clazz);
  56. }
  57. }

然后线程类中写一个无参的构造方法,在构造方法中,通过调用工具类中的 getBean() 方法就可以拿到实例了,程序在调用这个线程类时,会自动调用其无参的构造方法,在构造方法中我们将需要的bean对象注入,然后就可以正常使用了。

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import com.gdie.modules.oplog.service.LogDBOutput;
  3. import com.gdie.modules.oplog.util.ApplicationContextProvider;
  4. /**
  5. * 保存日志的线程
  6. * @Description :
  7. * @date : 2022年7月27日
  8. */
  9. public class LogInfo implements Runnable {
  10. @Autowired
  11. private LogDBOutput logDBOutput ApplicationContextProvider.getBean(LogDBOutput.class);
  12. @Override
  13. public void run() {
  14. // 这里就可以调用LogDBOutput中的方法了
  15. logDBOutput.addLog();
  16. }

文章评论

置顶