springboot反射调用方法导致依赖注入失效

        背景:是很普通的一个serviceImpl中,一个导入excel接口,中间调用了新增接口,新增接口时mybatis的dao为null,无法插入,很简单但是很不好解决的问题。

springboot反射调用方法导致依赖注入失效springboot反射调用方法导致依赖注入失效

       最开始我没发现是反射导致的问题, 接下来是我的思考历程。

        1、以为是bean容器没有注入,但是另一个serviceImpl也注入了这个Dao,能够成功使用,并且我在项目启动时打印出了所有的bean,确实注入进去了的。

        2、我以为是这个类没有初始化,但是这个类也加了@Service注解,应该能够正常使用。

        3、最后我发现当单独调用新增接口时能够正常新增,使用导出调用新增时不能正常使用。

        然后我试了一下正常的controller依赖注入调用service都可以,使用反射来调用方法的都不能注入,才发现是反射的问题。

        因为我写的反射是手动通过反射获得的Bean的实例,这种方式相当于我们new Bean(),此Bean的实例已完全脱离Spring容器,因此无法依赖注入

        错误:

    //反射, 获取类
    Class c = serviceContext.getClass(typeEnum.getCode());
    //对类进行实例化
    Object o = c.newInstance();
    //指定方法
    Method method = c.getDeclaredMethod("importFile", MultipartFile.class);
    //调用方法
    method.invoke(o, new Object[]{file});

        正确:修改成从bean容器中拿该类,并实例化,就能够进行依赖注入了。

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


@Component
public class SpringContextUtil implements ApplicationContextAware {

    // Spring应用上下文环境
    private static ApplicationContext applicationContext;
    /**
     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
     *
     * @param applicationContext
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextUtil.applicationContext = applicationContext;
    }
    /**
     * @return ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
     * 获取对象
     * @param name
     * @return Object
     * @throws BeansException
     */
    public static Object getBean(String name) throws BeansException {
        return applicationContext.getBean(name);
    }
    public static Object getBean(String name, Class cla) throws BeansException {
        return applicationContext.getBean(name, cla);
    }

}
    //反射, 获取类
    Class c = serviceContext.getClass(typeEnum.getCode());
    //获取首字母小写类名
    String simpleName = c.getSimpleName();
    String firstLowerName = simpleName.substring(0,1).toLowerCase() + simpleName.substring(1);
    //通过此方法去Spring容器中获取Bean实例
    Object o = SpringContextUtil.getBean(firstLowerName, c);
    //指定方法
    Method method = c.getDeclaredMethod("importFile", MultipartFile.class);
    //调用方法
    method.invoke(o, new Object[]{file});

上一篇:Spring IoC容器


下一篇:Android之自定义ViewGroup