SpringBoot-通过反射方式调用无依赖模块中的方法
1. 调用示例
private static final String COMMON_TASK_HANDLER_BEAN_NAME = "cn.jiangjiesheng.ecp.schedule.CommonTaskHandler";
try {
//有依赖时通过此方案获取: XxlJobRetry xxlJobRetry = (XxlJobRetry) BeansTool.getBean(sysRetryTask.getBeanName());
Object instance = InstanceCache.getOrCreateInstance(true, COMMON_TASK_HANDLER_BEAN_NAME);
ReflectUtils.getInstance().invokeMethod(COMMON_TASK_HANDLER_BEAN_NAME, "execute", instance, finalTaskNum);
} catch (Exception e) {
Log.showRedHighLightLog(true, LOG_TAG, "异步立即调用下载任务失败", e);
}
2. 代码文件
InstanceCache.java
package cn.jiangjiesheng.core.utils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* // 示例1:从 Spring 容器中获取或创建一个实例(推荐用于 Spring 管理的类)
* Object instance1 = InstanceCache.getOrCreateInstance(true, "com.example.ecpweb.CommonTaskHandler");
*
* // 示例2:通过反射构造函数创建实例(适用于非 Spring 类)
* Object instance2 = InstanceCache.getOrCreateInstance(false, "com.example.NonSpringClass");
*
* // 示例3:带参数的构造方法(只在 useSpring = false 时生效)
* Object instance3 = InstanceCache.getOrCreateInstance(false, "com.example.MyService", "Tom", 25);
*/
public class InstanceCache {
private static final Map<String, Object> instances = new ConcurrentHashMap<>();
public static Object getOrCreateInstance(boolean useSpring, String className, Object... args) throws Exception {
if (instances.containsKey(className)) {
return instances.get(className);
}
Object instance = ReflectUtils.getInstance().createInstance(useSpring, className, args);
instances.put(className, instance);
return instance;
}
}
ReflectUtils.java
package cn.jiangjiesheng.core.utils;
import cn.hutool.extra.spring.SpringUtil;
import com.envtoday.ecp.exception.GnException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* // 场景一:创建 Spring 管理的 Bean(自动注入依赖)
* Object instance = ReflectUtils.getInstance().createInstance(
* true,
* "com.example.ecpweb.CommonTaskHandler"
* );
*
* // 场景二:创建普通类(含构造参数)
* // 假设有类:MyService(String name, int age)
* Object instance = ReflectUtils.getInstance().createInstance(
* false,
* "com.example.MyService",
* "Tom",
* 25
* );
*/
public class ReflectUtils {
// 单例模式(可选)
private static final ReflectUtils INSTANCE = new ReflectUtils();
public static ReflectUtils getInstance() {
return INSTANCE;
}
private ReflectUtils() {}
/**
* 加载类
*/
public Class<?> loadClass(String className) throws ClassNotFoundException {
return Class.forName(className);
}
/**
* 创建类的实例(支持 Spring 管理的 Bean 和普通类)
*
* @param useSpring 是否使用 Spring 容器获取 Bean
* @param className 类名
* @param args 构造参数(可选)
* @return 实例对象
*/
public Object createInstance(boolean useSpring, String className, Object... args) throws Exception {
Class<?> clazz = loadClass(className);
if (useSpring) {
try {
// 尝试从 Spring 容器中获取 Bean (package cn.hutool.extra.spring;)
return SpringUtil.getBean(clazz);
} catch (Exception e) {
// 如果不是 Spring Bean,或者找不到对应的 Bean,尝试回退到反射创建
throw new GnException("Spring 环境中没有此bean:"+className);
}
}
// 如果不是 Spring Bean 或者 Spring 获取失败,则使用反射创建
if (args == null || args.length == 0) {
// 无参构造函数
Constructor<?> constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} else {
// 有参构造函数
Class<?>[] argTypes = getParameterTypes(args);
Constructor<?> constructor = clazz.getDeclaredConstructor(argTypes);
constructor.setAccessible(true);
return constructor.newInstance(args);
}
}
/**
* 获取方法对象
*/
public Method getMethod(String className, String methodName, Class<?>... parameterTypes) throws Exception {
Class<?> clazz = loadClass(className);
return clazz.getMethod(methodName, parameterTypes);
}
/**
* 调用方法(自动判断是否是静态方法),是否能获取到静态方法,未实测,还是能自动切换到invokeStaticMethod?
*/
public Object invokeMethod(String className, String methodName, Object instance, Object... args) throws Exception {
Class<?>[] argTypes = getParameterTypes(args);
Method method = getMethod(className, methodName, argTypes);
method.setAccessible(true);
return method.invoke(instance, args);
}
/**
* 调用静态方法
*/
public Object invokeStaticMethod(String className, String methodName, Object... args) throws Exception {
return invokeMethod(className, methodName, null, args);
}
/**
* 辅助方法:从参数数组中推断参数类型
*/
private Class<?>[] getParameterTypes(Object... args) {
if (args == null || args.length == 0) {
return new Class[0];
}
Class<?>[] types = new Class[args.length];
for (int i = 0; i < args.length; i++) {
types[i] = args[i].getClass();
}
return types;
}
// 可选:添加缓存机制(例如 Map<String, Class<?>>)提升性能
}
正文到此结束
- 本文标签: Java Spring Spring Boot
- 本文链接: https://code.jiangjiesheng.cn/article/372
- 版权声明: 本文由小江同学原创发布,转载请先联系本站长,谢谢。