Because the mapper of ServiceImpl is null, the following is the original implementation code:
// package name and class name
Class classzz = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
// Get the constructor object
Constructor constructor = null;
try {
constructor = classzz.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// Create an object using the constructor object
Object o = constructor.newInstance();
// Pass the method to be executed Pass the parameter type, if not, you can leave it out
Method method = classzz.getMethod("method name", long.class,String.class,String.class );
// invoke method, and pass parameters, if there are no parameters, you can leave them out
Object obj =method.invoke(o, 5,
"param1",
"param2");
In the post query mode, you need to ContextLoader.getCurrentWebApplicationContext() firstly, but you haven’t gone to invoke, so the ContextLoader.getCurrentWebApplicationContext() is null.
The final solution is as follows:
1. Create a new class 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 Common class to get the bean tool class in the Spring container
*/
@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("========In the general class you can get the applicationContext object by calling SpringBootBeanUtil.getApplicationContext()========");
System.out.println("========applicationContext="+ SpringBootBeanUtil.applicationContext +"========");
}
/**
* get applicationContext
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Get Bean by name.
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* Get Bean by class.
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* Return the specified bean by name, and Clazz
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
2. Call SpringBootBeanUtil.getApplicationContext(). When invoking, the first parameter is applicationContext.getBean(ServiceImplType). Refer to the following code for specific implementation.
try {
//Retrieve the created object from the ApplicationContext
// Do not create the serviceimpi object directly by reflection, because the object created by reflection cannot instantiate the dao interface
ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
//reflection creates the serviceimpi entity object, and the entity class
Class<? > ServiceImplType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
// Class<? > entityType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
//reflection set method parameters.
Method method = ServiceImplType.getDeclaredMethod("methodName",long.class,String.class,String.class );
// get the instantiated bean in the ApplicationContext according to class
method.invoke(applicationContext.getBean(ServiceImplType), 5,
"param1",
"param2");
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
LOGGER.error("\n onMessage Receive Processing Message Failed - {}", "methodName");
}
This solves the problem that the reflection calls ServiceImpland the mapper reports an error when it is null.