Java使用invoke反射调用方法导致@Value、@Auto

2020-05-08  本文已影响0人  远方_2019

发生背景:开发过程中使用到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> T getBean(Class<T> clazz) throws BeansException {

return applicationContext.getBean(clazz);

}

}

上一篇 下一篇

猜你喜欢

热点阅读