Java使用invoke反射调用方法导致@Value、@Autowired等注解失效

发生背景:开发过程中使用到invoke进行反射调用serviceImpl实现类的方法,在运行中发现采用反射方式调用会导致实现类中@value以及@Autowired注解失效,对应注解值都为null。

原因:因为在调用invoke反射方法时,Class是直接使用newInstance静态方法来实例化对象。所导致对应@value、@Autowired等注解失效。

PS:Spring的注解是在Spring实例化的时候扫描注入,当Spring实例化完毕之后如果再去newInstance一个新的对象显然是不受Spring管理了,所以相应的注解都是注入为null。

Class baseService = serviceClassMap.get(taskRecord.getPlateform());
// 获取指定Method方法
String methodStr = CommonMethodEnum.hasMethod(taskRecord.getType());
Method method = baseService.getMethod(methodStr,Long.class,File.class);
method.invoke(baseService.newInstance(), taskRecord.getId(), file);

解决方案:使用SpringContext上下文获取对应Bean,从而避免注解失效。

method.invoke(SpringUtil.getBean(baseService), taskRecord.getId(), file);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SpringUtil工具类~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

采用实现接口ApplicationContextAware从而获取ApplicationContext

说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring初始化时,会通过该方法将ApplicationContext对象注入。

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

 

你可能感兴趣的:(Java笔记,日常BUG,java)