基於spring通過例項方法名進行方法呼叫
阿新 • • 發佈:2020-10-22
1.spring物件例項的相關方法
@Component public final class SpringUtils implements BeanFactoryPostProcessor { /** Spring應用上下文環境 */ private static ConfigurableListableBeanFactory beanFactory; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtils.beanFactory = beanFactory; } /** * 獲取物件 * @param name * @return Object 一個以所給名字註冊的bean的例項 * @throws org.springframework.beans.BeansException * */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); } /** * 獲取型別為requiredType的物件 * @param clz * @return * @throws org.springframework.beans.BeansException * */ public static <T> T getBean(Class<T> clz) throws BeansException { T result = (T) beanFactory.getBean(clz); return result; } /** * 如果BeanFactory包含一個與所給名稱匹配的bean定義,則返回true * @param name * @return boolean */ public static boolean containsBean(String name) { return beanFactory.containsBean(name); } /** * 判斷以給定名字註冊的bean定義是一個singleton還是一個prototype。 如果與給定名字相應的bean定義沒有被找到,將會丟擲一個異常(NoSuchBeanDefinitionException) * @param name * @return boolean * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return beanFactory.isSingleton(name); } /** * @param name * @return Class 註冊物件的型別 * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { return beanFactory.getType(name); } /** * 如果給定的bean名字在bean定義中有別名,則返回這些別名 * @param name * @return * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * */ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return beanFactory.getAliases(name); } /** * 獲取aop代理物件 * * @param invoker * @return */ @SuppressWarnings("unchecked") public static <T> T getAopProxy(T invoker) { return (T) AopContext.currentProxy(); } }
2.根據指定的例項、方法名、引數進行方法呼叫
public class JobInvokeUtil { /** * 執行方法 */ public static void invokeMethod(String invokeTarget) throws Exception { //擷取例項名稱; String beanName = getBeanName(invokeTarget); //擷取要呼叫的方法名稱 String methodName = getMethodName(invokeTarget); //獲取方法的相關引數 List<Object[]> methodParams = getMethodParams(invokeTarget); if (!isValidClassName(beanName)) { Object bean = SpringUtils.getBean(beanName); //呼叫任務方法 invokeMethod(bean, methodName, methodParams); } else { Object bean = Class.forName(beanName).newInstance(); invokeMethod(bean, methodName, methodParams); } } /** * 呼叫任務方法 * * @param bean 目標物件 * @param methodName 方法名稱 * @param methodParams 方法引數 */ private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!CollectionUtils.isEmpty(methodParams) && methodParams.size() > 0) { Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams)); method.invoke(bean, getMethodParamsValue(methodParams)); } else { Method method = bean.getClass().getDeclaredMethod(methodName); method.invoke(bean); } } /** * 校驗是否為為class包名 * * @param * @return true是 false否 */ public static boolean isValidClassName(String invokeTarget) { return StringUtils.countMatches(invokeTarget, ".") > 1; } /** * 獲取bean名稱 * * @param invokeTarget 目標字串 * @return bean名稱 */ public static String getBeanName(String invokeTarget) { String beanName = StringUtils.substringBefore(invokeTarget, "("); return StringUtils.substringBeforeLast(beanName, "."); } /** * 獲取bean方法 * * @param invokeTarget 目標字串 * @return method方法 */ public static String getMethodName(String invokeTarget) { String methodName = StringUtils.substringBefore(invokeTarget, "("); return StringUtils.substringAfterLast(methodName, "."); } /** * 獲取method方法引數相關列表 * * @param invokeTarget 目標字串 * @return method方法相關引數列表 */ public static List<Object[]> getMethodParams(String invokeTarget) { String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); if (StringUtils.isEmpty(methodStr)) { return null; } String[] methodParams = methodStr.split(","); List<Object[]> classs = new LinkedList<>(); for (int i = 0; i < methodParams.length; i++) { String str = StringUtils.trimToEmpty(methodParams[i]); // String字串型別,包含' if (StringUtils.contains(str, "'")) { classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class }); } // boolean布林型別,等於true或者false else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false")) { classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); } // long長整形,包含L else if (StringUtils.containsIgnoreCase(str, "L")) { classs.add(new Object[] { Long.valueOf(StringUtils.replace(str, "L", "",-1)), Long.class }); } // double浮點型別,包含D else if (StringUtils.containsIgnoreCase(str, "D")) { classs.add(new Object[] { Double.valueOf(StringUtils.replace(str, "D", "",-1)), Double.class }); } // 其他型別歸類為整形 else { classs.add(new Object[] { Integer.valueOf(str), Integer.class }); } } return classs; } /** * 獲取引數型別 * * @param methodParams 引數相關列表 * @return 引數型別列表 */ public static Class<?>[] getMethodParamsType(List<Object[]> methodParams) { Class<?>[] classs = new Class<?>[methodParams.size()]; int index = 0; for (Object[] os : methodParams) { classs[index] = (Class<?>) os[1]; index++; } return classs; } /** * 獲取引數值 * * @param methodParams 引數相關列表 * @return 引數值列表 */ public static Object[] getMethodParamsValue(List<Object[]> methodParams) { Object[] classs = new Object[methodParams.size()]; int index = 0; for (Object[] os : methodParams) { classs[index] = (Object) os[0]; index++; } return classs; } }
注:程式碼取材於"ruoyi”定時任務呼叫部分