1. 程式人生 > 實用技巧 >基於spring通過例項方法名進行方法呼叫

基於spring通過例項方法名進行方法呼叫

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”定時任務呼叫部分