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

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

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

        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});

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值