SpringBoot在Thread线程中注入Bean无效的解决方式

作者:hayaqi0504 
来源:CSDN 
原文:https://blog.csdn.net/hayaqi0504/article/details/85233804 
------------------------------------------------------------------------------------------------------------------

解决方法

  1. 使用内部类
  2. 使用构造函数传入
  3. 获取全局Bean,然后根据名字获取。

内部类

@Controller
public class SomeController{
    // 通过注解注入封装线程的Bean
    @AutoWired
    SomeThread someThread;
    @ResponseBody
    @RequestMapping("test")
    String testInjection(){
        // 通过注入的Bean启动线程
        someThread.execute();
    }
}
 
@Component
public class SomeThread {
    // 封装Bean中注入服务
    @AutoWired
    SomeService someService
    public void execute() {
        new Worker().start();
    }
    // 线程内部类,Thread或者Runnable均可
    private class Worker extends Thread {
        @Override
        public void run() {
            // do something...
            SomeThread.this.someService.doSomething();
            // 此时someService已被注入,非null.
        }
    }
}

构造函数

@Controller
public class SomeController{
    // 通过注解注入Service
    @AutoWired
    SomeService someService;
    @ResponseBody
    @RequestMapping("test")
    String testInjection(){
        // 通过构造函数从外部引入
        new Worker(someService).start();
    }
}
 
public class SomeThread {
    private SomeService someService;
    public SomeThread(SomeService someService){
        // 通过构造函数从外部引入
        this.someService  = someService;
    }
    @Override
    public void run() {
        // do something...
        someService.doSomething();
        // 此时someService非null.
    }
}

全局bean集合 根据bean名字获取

1.工具类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;



@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

2.使用方式

public class ThreadA implements Runnable {
    private Service service;
    public ThreadA() {
        this.service = ApplicationContextProvider.getBean(Service.class);
    }

    @Override
    public void run() {
    //TO BE DONE
    }
}

注解的有效范围
如果Application类所在的包为com.test.app,则只会扫描com.test.app包及其子包内扫描。
如果有com.test.pc,如要扫描到com.test.pc下面的类,那么需要在启动类中
配置注解@ComponentScan(basePackages={“com.test”}),
注:一个类如果要被注解扫描到需要满足的条件
类必须在启动类同一个包下面或者在启动类包子包中
被扫描的类如果不再启动类所在包及其子包中,那么需要在测试类上配置
@ComponentScan注解把需要被扫描的包配置进来
测试类必须在启动类当前目录或者启动类的目录的子目录下面
 

猜你喜欢

转载自blog.csdn.net/yuhan_0590/article/details/86347537
今日推荐