springboot 使用反射调用ServiceImpl,报错:
java.lang.NullPointerException
是由于ServiceImpl的
mapper为null
导致的,以下为原实现代码:
// 包名+类名
Class classzz = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
// 获取构造器对象
Constructor constructor = null;
try {
constructor = classzz.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// 利用构造器对象创建一个对象
Object o = constructor.newInstance();
// 传递需要执行的方法 传递参数类型,如果没有可以不用填写
Method method = classzz.getMethod("方法名称", long.class,String.class,String.class );
// invoke 方法,并传递参数,如果没有参数,可以不用填写
Object obj =method.invoke(o, 5,
"param1",
"param2");
后查询方式,需要先
ContextLoader.getCurrentWebApplicationContext()
,但是还没有走到invoke,获取的
ContextLoader.getCurrentWebApplicationContext()
就为null。
最终解决实现的方式如下:
1.新建类 SpringBootBeanUtil
package com.smart.hyd.common.utils.reflect;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* SpringBoot 普通类获取Spring容器中的bean工具类
*/
@Component
public class SpringBootBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringBootBeanUtil.applicationContext == null) {
SpringBootBeanUtil.applicationContext = applicationContext;
}
System.out.println("========ApplicationContext配置成功========");
// System.out.println("========在普通类可以通过调用SpringBootBeanUtil.getApplicationContext()获取applicationContext对象========");
System.out.println("========applicationContext="+ SpringBootBeanUtil.applicationContext +"========");
}
/**
* 获取applicationContext
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
2.调用
SpringBootBeanUtil.getApplicationContext()
,在invoke的时候,第一个参数applicationContext.getBean(ServiceImplType),具体实现参照下面代码。
try {
//从ApplicationContext中取出已创建好的的对象
//不可直接反射创建serviceimpi对象,因为反射创建出来的对象无法实例化dao接口
ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
//反射创建serviceimpi实体对象,和实体类
Class<?> ServiceImplType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
// Class<?> entityType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
//反射设置方法参数。
Method method = ServiceImplType.getDeclaredMethod("方法名称",long.class,String.class,String.class );
//在ApplicationContext中根据class取出已实例化的bean
method.invoke(applicationContext.getBean(ServiceImplType), 5,
"param1",
"param2");
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
LOGGER.error("\n onMessage接收处理消息失败 - {}", "方法名称");
}
这样就解决了反射调用ServiceImpl,mapper为null报错的问题。
参照解决方法的地址:
版权声明:本文为ying456baby原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。