Call methods of other layers through reflection in the service layer in the project

Sometimes in development, some methods are in the controller layer, but need to be called again in the service layer. Copying the methods of the controller layer to the service is the simplest and rude method, but this will inevitably increase unnecessary layers of repeated code. At this time Method calls can be invoked through reflection.

reflection tools

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 这是为了反射获取Component,解决反射调用Service层方法@Autowired注入为空的问题
 *
 * @author:user
 * @date: 2022-02-09 15:47
 */
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    
    

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
    
    
        applicationContext = context;
    }

    /**
     * 获取bean
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
    
    
        if (null == applicationContext) {
    
    
            return null;
        }

        return applicationContext.getBean(clazz);
    }

    public static <T> T getBean(String name, Class<T> clazz) {
    
    
        if (null == applicationContext) {
    
    
            return null;
        }

        return applicationContext.getBean(name, clazz);
    }

    /**
     * 使用反射调用bean中的方法
     *
     * 注意!!!
     * 这个方法只支持调用bean中参数列表只有一个参数的方法,且参数类型为String,返回类型为String。
     * 因为参数都是String类型的,如果使用String不定参数的话,JVM不知道前面的不定长度参数有多长,下一个参数是从哪里开始,会报错。
     *
     * 如果不满足以上要求,又需要反射调用bean中的方法,可以模仿这个方法自定义。
     *
     * @param className    类的全限定名
     * @param methodName  方法名,这里指BatchWaybillServiceImpl中的私有方法的方法名
     * @param methodParam 参数名,这里指BatchWaybillServiceImpl中的私有方法的参数名
     * @return
     * @throws Exception
     */
    public static String getResult(String className, String methodName, String methodParam) throws Exception {
    
    
        Class<?> c = Class.forName(className);

        Object bean = getBean(c);  //获取要创建的bean

        Method method = c.getDeclaredMethod(methodName, methodParam.getClass()); //getDeclaredMethod能找到所有的方法
        method.setAccessible(true);  //允许访问私有的方法

        return (String) method.invoke(bean, methodParam);
    }

    //methodParamClass为了解决传入不定参数存在为空,通过getClass(T... params)获取不到.class的情况
    public static <T> Object getMethod(String className, String methodName, Class[] methodParamClass, T... methodParam) throws Exception {
    
    
        Class<?> c = Class.forName(className);

        Object bean = getBean(c);  //获取要创建的bean

        Method method = c.getDeclaredMethod(methodName, methodParamClass); //getDeclaredMethod能找到所有的方法
        method.setAccessible(true);  //允许访问私有的方法
        return method.invoke(bean, methodParam);
    }

    /**
     * 获取不定参数的class,所传参数不能为空
     * @param params
     * @param <T>
     * @return
     */
    public static <T> Class[] getClass(T... params) {
    
    
        Class[] classArray = new Class[params.length];

        for (int i = 0, j = params.length; i < j; i++) {
    
    
            if (null != params[i])
                classArray[i] = params[i].getClass();
            else
                throw new RuntimeException("不定参数存在空值!");
        }

        return classArray;
    }

    //根据传入.class获取class数组
    public static Class[] getClass(Class... params) {
    
    
        Class[] classArray = new Class[params.length];

        for (int i = 0; i < params.length; i++) {
    
    
            classArray[i] = params[i];
        }

        return classArray;
    }
}

Then call it in the service and
insert image description here
test it, and successfully call the method of the controller layer.

Refer to this buddy's blog:
https://blog.csdn.net/swing12/article/details/121657200

Guess you like

Origin blog.csdn.net/studio_1/article/details/124669315