1、说明
java中利用反射去动态执行一个普通类的方法一般是非常简单的,但是遇到spring管理的bean类可能就不太好做了,这里给出以下方法解决这个问题。主要思路是用spring上下文获取bean的实例对象,然后用目标对象的代理对象反射执行方法。
2、工具类代码
package com.ourlang.dataextract.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * 动态获取spring管理的bean实例对象 * spring上下文工具类 * https://github.com/ourlang * @author ourlang */ @Component("springContextUtil") public class SpringContextUtil implements ApplicationContextAware { /** * Spring应用上下文环境 */ private static ApplicationContext applicationContext; /** * 实现ApplicationContextAware接口的回调方法,设置上下文环境 */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } /** * 获得spring上下文 * * @return ApplicationContext spring上下文 */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 获取bean * * @param name service注解方式name为小驼峰格式 * @return Object bean的实例对象 */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T) applicationContext.getBean(name); } /** * 获取bean * * @param clz service对应的类 * @return Object bean的实例对象 */ @SuppressWarnings("unchecked") public static <T> T getBean(Class<?> clz) throws BeansException { return (T) applicationContext.getBean(clz); } }
3、调用测试
@Test public void testSpringContext(){ // 获取bean,注意这里用实现类的接口强转去获得目标bean的代理对象,才能成功执行下面的反射方法 //com.ourlang.dataextract.service.impl.SInpatientInRoundsServiceImpl@246dafe6 Object obj= SpringContextUtil.getBean(ISInpatientInRoundsService.class); // 获取方法,这个hello实际上是父类的方法,后面String.class是参数类型 Method method= ReflectionUtils.findMethod(obj.getClass(),"hello",String.class); // 反射执行方法,ourlang是后面传递的参数 ReflectionUtils.invokeMethod(method,obj,"ourlang"); }