AOP-基于JDK动态代理实现

发布时间 2023-11-09 09:43:42作者: DoubleFishes

参照上上篇文章,JDK动态代理,继承InvocationHandler。

 

目标对象继承的接口:ICal.java

public interface ICal {
    public int add(int n1, int n2);
    public int sub(int n1, int n2);
    public int mul(int n1, int n2);
    public int div(int n1, int n2);
}

 

目标对象类:CalImpl.java(被横切的对象。需要在方法执行前后添加日志打印)

public class CalImpl implements ICal {

    public int add(int n1, int n2) {
        int res = n1 + n2;
//        System.out.printf("加法:%d + %d = %d\n", n1, n2, res);
        return res;
    }

    public int sub(int n1, int n2) {
        int res = n1 - n2;
//        System.out.printf("减法:%d + %d = %d\n", n1, n2, res);
        return res;
    }

    public int mul(int n1, int n2) {
        int res = n1 * n2;
//        System.out.printf("乘法:%d + %d = %d\n", n1, n2, res);
        return res;
    }

    public int div(int n1, int n2) {
        int res = n1 / n2;
//        System.out.printf("除法:%d + %d = %d\n", n1, n2, res);
        return res;
    }
}

 

代理类:MyInvocationHandler.java(JDK代理实现方式,继承InvocationHandler。)

public class MyInvocationHandler implements InvocationHandler {
    private Object target = null;

    /**
     * 绑定目标,生成代理对象
     * @param target
     * @return
     */
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 调用invoke()方法,通过反射调用目标对象方法。插入'通知'代码
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName() + "方法的参数是:" + Arrays.toString(args));  // 方法执行前
        Object res = method.invoke(this.target, args);
        System.out.println(method.getName() + "方法的结果是:" + res);  // 方法执行后
        return res;
    }
}

 

测试调用方法,加上日志打印

public class TestInvocationHandler {
    public static void main(String[] args) {
        // 目标对象
        ICal ICal = new CalImpl();  
        
        // 生成代理对象,绑定目标对象
        MyInvocationHandler handler = new MyInvocationHandler();
        ICal proxy = (ICal) handler.bind(ICal);

        // 调用方法,横切增加日志打印
        proxy.add(3, 1);
        proxy.div(3, 1);
        proxy.sub(3, 1);
        proxy.mul(3, 1);
    }
}

 

输出:

add方法的参数是:[3, 1]
add方法的结果是:4
div方法的参数是:[3, 1]
div方法的结果是:3
sub方法的参数是:[3, 1]
sub方法的结果是:2
mul方法的参数是:[3, 1]
mul方法的结果是:3