页面效果:
代码:
SpringContextUtil.java (com.nsoft.dgc.dtschedule.exclass.SpringContextUtil)
package com.nsoft.dgc.dtschedule.exclass; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * @Description: 获得容器中注入的对象 * 参考:https://blog.csdn.net/weixin_43944305/article/details/106664830 * https://wenku.baidu.com/view/e24f1e15598102d276a20029bd64783e09127d01.html * http://www.manongjc.com/article/92044.html * * @date: 2022.06.16 */ @Component public class SpringContextUtil implements ApplicationContextAware { // Spring应用上下文环境 private static ApplicationContext applicationContext; /** * 实现ApplicationContextAware接口的回调方法,设置上下文环境 * * @param applicationContext */ @Override public void setApplicationContext(ApplicationContext applicationContext) { SpringContextUtil.applicationContext = applicationContext; } /** * 获得Spring应用上下文 * @return ApplicationContext */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 获取对象bean 通过id或name去查找获取bean * @param name name默认 = 类名(首字母小写) 参数name表⽰IOC容器中已经实例化的bean的id或者name,且⽆论是id还是name都要求在IOC容器中是唯⼀的不能重名。 * 首字母小写的对象名称: 例如 com.nsoft.dgc.dtschedule.service.impl.DgcTaskServiceImpl ,可以加上注解@Service,默认了类名的首字母小写的名称,即等同于 @Service("dgcTaskServiceImpl"), * 另外注意 dgcTaskServiceImpl 必须是唯一的,不能重名, * 另由于bean类需要一个无参构造方法,显然容器并不能创建接口的bean,故抽象类只能作为其他bean的父类 * @return Object * @throws BeansException */ public static Object getBean(String name) throws BeansException { return applicationContext.getBean(name); } /** * 获取对象bean * @param name 同上面的解释 * @param cla 对象类(注意:必须是已经被注入到Spring容器的类才可以) * @return Object * @throws BeansException */ public static Object getBean(String name, Class cla) throws BeansException { return applicationContext.getBean(name, cla); } }
ExcuteClass.java (com.nsoft.dgc.dtschedule.exclass.ExcuteClass) 方法调用ExcuteClassMethod()方法即可
package com.nsoft.dgc.dtschedule.exclass; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.Feature; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.Map; /** * @Description: 根据传过来的参数执行类方法(反射原理) * @date: 2022.06.14 */ @Component public class ExcuteClass { final protected Logger logger = LogManager.getLogger(getClass()); /** * @Description: 根据所传参数,反射方法,并执行 * @param classPath: 类路径 例如:com.nsoft.dgc.dtschedule.service.impl.DgcTaskServiceImpl * @param methodName: 方法名称 注意方法名称及大小写应与实际方法完全一致 * @param parameters: 参数,以json格式编写,参数顺序与实际参数顺序相同;当前支持的参数类型包括int、long、double、float、String、boolean、Short、Integer、Long、Double、Float, * 例如{int:12,long:123454567,String:'lala',boolean:true,Float:12.12,Double:null} * @return: void * @exception/throws: * @date: 2022/6/16 */ public void ExcuteClassMethod(String classPath,String methodName,String parameters) throws RuntimeException{ Class clazz = null;//类 String simpleName = null;//类名 String firstLowerName = null; //首字母小写的类名 Method method = null;//方法 Object instance = null;//spring容器中的对象实例 Class[] tempKey = null;//参数类型数字 Object[] tempValue = null;//参数数值数组 /**1.获得类相关信息**/ try{ clazz = Class.forName(classPath);//通过类路径获得类 这里的classPath路径是类的全路径,从包名到类名 simpleName = clazz.getSimpleName();//获得类名称 firstLowerName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); //获得首字母小写的类名称 }catch (Exception e){ logger.error("获得类及名称时报错:classPath="+classPath+";clazz="+clazz+";simpleName="+simpleName+";firstLowerName="+firstLowerName,e); throw new RuntimeException(e); } /**2.去Spring容器中获得类对象**/ try { //通过此方法去Spring容器中获取对象实例(此类必须是已经注入到Spring容器中的。注入Spring容器中是指使用@Controller@Service@Mapper@Component等注解注入的bean(接口interface不行),由spring进行管理的类) instance = SpringContextUtil.getBean(firstLowerName, clazz); }catch (Exception e){ logger.error("spring容器获得对象时报错:firstLowerName="+firstLowerName+";clazz="+clazz,e); throw new RuntimeException(e); } /**3.获得参数,将参数类型放到Class[]数组中,将参数数值放到Object[]数组中**/ try{ if(null != parameters &&!"".equals(parameters)){ int i = 0; JSONObject jsonObject = JSONObject.parseObject(parameters, Feature.OrderedField);//将参数转换为json(Feature.OrderedField参数保证转换时顺序不变) if (!jsonObject.isEmpty()) { tempKey = new Class[jsonObject.size()]; tempValue = new Object[jsonObject.size()]; for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {//fastjson解析方法 进行遍历 向tempKey 和 tempValue 数组赋值 this.getClass(entry.getKey(),entry.getValue(),i,tempKey,tempValue); i++; } } } }catch (Exception e){ logger.error("参数转换时报错,请检查参数的正确性,错误信息为:"+ e.getMessage()); throw new RuntimeException(e); } /**4.获得指定方法。两种方式,一种是不知道参数类型时,遍历类中所有的方法,对方法名称进行匹配,第二种是已知方法的参数类型,可直接获得方法**/ try{ //获得clazz类中所有的方法 // tempClass = clazz.getMethods(); // if(tempClass !=null && tempClass.length>0){ // for(int i =0;i<tempClass.length;i++){ // if(methodName.equals(tempClass[i].getName())){ // method = tempClass[i];//获得此类中的方法 // break; // } // } // } //指定方法(在已知方法参数的类型情况下,用下面这个可直接获得方法) method = clazz.getDeclaredMethod(methodName,tempKey); }catch (Exception e){ logger.error("获得方法时报错:clazz="+clazz+";method="+method+";methodName="+methodName+"tempKey="+(tempKey!=null?tempKey.toString():null),e); throw new RuntimeException(e); } /**5.执行方法**/ try{ //调用方法 method.invoke(instance,tempValue);//object为对象实例, tempValue为参数数值数组 }catch (Exception e){ logger.error("方法执行时报错:method="+method+";object="+instance+";tempValue="+(tempValue!=null?tempValue.toString():null),e); throw new RuntimeException(e); } } /** * @Description: 参数类型转换,并赋值(当前仅支持的参数类型包括int、long、double、float、String、boolean、Short、Integer、Long、Double、Float) * @param paraType: 参数类型 * @param paraValue: 参数值 * @param i: 第几个参数 从0开始 * @param tempKey: 返回 参数类型数组 * @param tempValue: 返回 参数数值数组 * @return: void * @exception/throws: * @date: 2022/6/17 */ public void getClass(Object paraType,Object paraValue,int i,Class[] tempKey,Object[] tempValue) throws RuntimeException { boolean isMatch = false;//是否有匹配的类型 try { if ("Short".equals(paraType)) { tempKey[i] = Short.class; tempValue[i] = paraValue == null ? null : Short.valueOf(String.valueOf(paraValue)); isMatch = true; } else if ("Integer".equals(paraType)) { tempKey[i] = Integer.class; tempValue[i] = paraValue == null ? null : Integer.valueOf(String.valueOf(paraValue)); isMatch = true; } else if ("Long".equals(paraType)) { tempKey[i] = Long.class; tempValue[i] = paraValue == null ? null : Long.valueOf(String.valueOf(paraValue)); isMatch = true; } else if ("Double".equals(paraType)) { tempKey[i] = Double.class; tempValue[i] = paraValue == null ? null : Double.valueOf(String.valueOf(paraValue)); isMatch = true; } else if ("Float".equals(paraType)) { tempKey[i] = Float.class; tempValue[i] = paraValue == null ? null : Float.valueOf(String.valueOf(paraValue)); isMatch = true; } else if ("int".equals(paraType)) { tempKey[i] = int.class; tempValue[i] = Integer.valueOf(String.valueOf(paraValue)).intValue(); isMatch = true; } else if ("long".equals(paraType)) { tempKey[i] = long.class; tempValue[i] = Long.valueOf(String.valueOf(paraValue)).longValue(); isMatch = true; } else if ("double".equals(paraType)) { tempKey[i] = double.class; tempValue[i] = Double.valueOf(String.valueOf(paraValue)).doubleValue(); isMatch = true; } else if ("float".equals(paraType)) { tempKey[i] = float.class; tempValue[i] = Float.valueOf(String.valueOf(paraValue)).floatValue(); isMatch = true; } else if ("String".equals(paraType)) { tempKey[i] = String.class; tempValue[i] = paraValue == null ? null : String.valueOf(paraValue); isMatch = true; } else if ("boolean".equals(paraType)) { tempKey[i] = boolean.class; tempValue[i] = paraValue; isMatch = true; } if (!isMatch){ logger.error("类型paraType="+paraType+"不匹配,不支持此数据类型"); throw new Exception("类型paraType="+paraType+"不匹配,不支持此数据类型"); } } catch (Exception e) { logger.error("第" + (i + 1) + "个参数转换时发生错误,错类型paraType=" + paraType + ";数值paraValue=" + paraValue ,e); throw new RuntimeException(e); } } }
本文来自博客园,作者:东方飘雪,转载请注明原文链接:https://www.cnblogs.com/zdyang/p/16954705.html