问题:使用@Autowired无法注入Bean对象

问题

在公司的一个项目开发时,遇到了一个类的属性无法注入的问题

public class DemoController extends BaseController implements BussinessProcessHandler {

    @Autowired
    DemoApi demoApi;
    
    public void demo() {
        demoApi.DemoService();
    }

如上代码运行中报空指针异常,demoApi的实例为nullspring容器没有注入Bean

原因

起先认为是spring没有扫描到组件。spring boot的注解@SpringBootApplication继承了扫描注解@ComponentScan,默认扫描是当前包及其子包下的所有目录,查看目录结构是没有问题的。所以不是扫描的问题。

后来发现这个类DemoController的实例是反射生成的,并不由spring容器管理。

spring自动注入对象是通过创建一个BeanFactory并传入applicationContext配置文件对象,然后调用BeanFactorygetBean方法来实现相互依赖的对象获取和装配的。如果被注入的容器没有在spring bean中配置,而是通过反射途径生成,不能获取BeanFactory,就意味着不能进行自动注入。

解决办法

自己创建一个SpringUtil工具类组件,实现BeanFactoryAware或者ApplicationContextAwarespring提供的接口,并通过实例手动获取Spring管理的bean

@Component
public class SpringUtil implements ApplicationContextAware {
    //ApplicationContext对象是Spring开源框架的上下文对象实例,在项目运行时自动装载Handler内的所有信息到内存。
    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }
    
    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    
    //通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
    
    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    
    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
    
}

手动获取bean实例

public class DemoController extends BaseController implements BussinessProcessHandler {

    //@Autowired
    //DemoApi demoApi;
    
    public void demo() {
        //通过class获取bean
        DemoApi demoApi=SpringUtil.getBean(DemoApi.class);
        demoApi.DemoService();
    }

这样再运行demoApi就不为null了。

你可能感兴趣的:(开发问题)