普通的java反射调用一个方法的例子如下
import java.lang.reflect.Method;
public class ReflectionExample { public static void main(String[] args) { try { Class<?> clazz = Class.forName("TestClass");
Object instance = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getMethod("sayHello", String.class);
method.invoke(instance, "World"); } catch (Exception e) { e.printStackTrace(); } } }
class TestClass { public void sayHello(String name) { System.out.println("Hello, " + name + "!"); } }
|
这样的方式实例化的对象与被spring管理的bean对象有着本质的不同
spring的bean都是动态代理对象
而自己手动实例化的对象里面的依赖注入,注解等都会失效
正确的方式是从spring容器中获取bean对象,如下是工具类,可以根据类或者名称或者类和名称获取bean
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;
@Component public class SpringBootBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringBootBeanUtil.applicationContext == null) { SpringBootBeanUtil.applicationContext = applicationContext; } }
public static ApplicationContext getApplicationContext() { return applicationContext; }
public static Object getBean(String name) { return getApplicationContext().getBean(name); }
public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); }
public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); }
}
|
类与方法示例:
package org.jeecg.modules.fsevent.server.job;
import java.util.Arrays;
import javax.annotation.Resource;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.vo.SysPositionModel; import org.jeecg.modules.fsevent.constant.FsEventConstant; import org.jeecg.modules.fsevent.util.JobUtil; import org.jeecg.modules.tps.api.TpsFsJobApi; import org.springframework.stereotype.Component;
import com.lark.oapi.service.corehr.v2.model.I18n; import com.lark.oapi.service.corehr.v2.model.Job;
import cn.hutool.core.util.StrUtil;
@Component public class MasterJob { @Resource private TpsFsJobApi tpsFsJobApi; @Resource private ISysBaseAPI sysBaseAPI;
@Transactional(rollbackFor = Exception.class) @DS("feishupersondev") public void jobUpdated(String eventEntityJson) { String jobId = JobUtil.checkJobEventEntity(eventEntityJson); Result<Job> feignRes = tpsFsJobApi.searchOneJobInfo(jobId); if (!feignRes.isSuccess()) { throw new RuntimeException(feignRes.getMessage()); }
Job job = feignRes.getResult(); String code = job.getCode(); if (StrUtil.isBlank(code)) { throw new RuntimeException("飞书远程查询职位信息,职位编码为空"); }
SysPositionModel oldSysPositionModel = sysBaseAPI.getSysPositionByCode(code); if (oldSysPositionModel == null) { throw new RuntimeException("主库不存在该职务编码:" + code + ",无法更新"); }
SysPositionModel sysPositionModel = new SysPositionModel(); I18n nameI18n = Arrays.stream(job.getName()) .filter(name -> FsEventConstant.LanguageCode.CHINESE.equals(name.getLang())).findFirst().orElse(null); if (nameI18n == null) { throw new RuntimeException("更新职位没有中文名称"); } sysPositionModel.setId(oldSysPositionModel.getId()).setCode(job.getCode()).setName(nameI18n.getValue()) .setStatus(job.getActive() ? 1 : 0).setUpdateBy("system"); boolean res = sysBaseAPI.updateSysPosition(sysPositionModel); if (!res) { throw new RuntimeException("职位更新失败"); } } }
|
方法调用示例:
try { String beanName = "masterJob"; String methodName = "jobUpdated"; String className = "org.jeecg.modules.fsevent.server.job.MasterJob"; Class<?> aClass = Class.forName(className); Method method1 = aClass.getMethod(methodName, String.class); Object bean1 = SpringBootBeanUtil.getBean(beanName, aClass); method1.invoke(bean1, "111"); } catch (Exception e) { log.error("反射执行事件失败,执行id:{}", result.getId(), e); String logInfo; if (e instanceof ClassNotFoundException) { logInfo = "类未找到: " + e.getMessage(); } else if (e instanceof NoSuchMethodException) { logInfo = "方法: " + e.getMessage(); } else if (e instanceof IllegalAccessException) { logInfo = "无法访问目标方法: " + e.getMessage(); } else if (e instanceof InvocationTargetException) { Throwable cause = e.getCause(); if (cause != null) { logInfo = cause.getMessage(); } else { logInfo = e.getMessage(); } } else { logInfo = e.getMessage(); } }
|