情况是这样的
我写了个方法,通过反射调用一组类中的特定方法(就叫它test吧),当method中使用了用@Autowired注入的service时,这个service会报空指针错误,来看看解决方案吧:
报错代码
/**写一个方法通过反射调用其他类的方法*/
public Class doController{
public void dotest(String arr){
//获取类
Class<?> classz = Class.forName("com.anna.testController");
//获取对象
Object obj = classz.newInstance();
//获取方法
Method method = obj.getDeclaredMethod("test",String.Class);
//调用方法(第一个参数为方法名,后面跟方法参数)
method .invoke("test","arr");
}
}
/**这个类中的test方法,被反射调用*/
public Class testController{
@Autowired
private TestServiceImpl testServiceImpl;
public void test(String arr){
//testServiceImpl报空指针错误
testServiceImpl.doSomething(arr);
}
}
报错原因
反射的类无法被spring管理
解决办法
手动对要反射的类完成@Autowired效果,托管给spring,只需将主调方法改成这种即可:
/**写一个方法通过反射调用其他类的方法*/
public Class doController{
@Autowired
private ApplicationContext applicationContext;
public void dotest(String arr){
//获取类
Class<?> classz = Class.forName("com.anna.testController");
//获取对象
//Object obj = classz.newInstance();
//换成这两句就成了
Object obj = applicationContext.getBean(classz );
applicationContext.getAutowireCapableBeanFactory().autowireBean(obj);
//获取方法
Method method = obj.getDeclaredMethod("test",String.Class);
//调用方法(第一个参数为方法名,后面跟方法参数)
method .invoke("test","arr");
}
}
Tips
1、大佬同事说,反射效率比较慢,推荐使用策略模式
2、除了这种方式,还有一个更机械的方法,就是一条调用流水线全都用newInstance(),那就是不用spring托管了,不推荐