Spring学习笔记十三---动态代理

AOP
代码混乱,维护成本高
代码分散



动态代理
使用代理把对象包起来
代理对象取代原有对象,对原始对象调用都要通过代理,代理对象决定是否,何时调用原始对象。


AOP
关注点在切面业务逻辑编程,对原有代码没有影响。
切面: 横切关注点,如:日志。
通知:切面里面的方法
目标:被通知的对象target
代理: proxy对象
连接点:程序特定位置。方法执行前,后。方法抛出异常后。
切点:通过切点定位到连接点。

package aop;


public interface ICal {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}

package aop;



public class CalImpl implements ICal {
    @Override
    public int add(int i, int j) {
        return i + j;
    }

    @Override
    public int sub(int i, int j) {
        return i - j;
    }

    @Override
    public int mul(int i, int j) {
        return i * j;
    }

    @Override
    public int div(int i, int j) {
        return i / j;
    }
}

package aop;


import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class CalProxy {
    //要代理的对象
    private  ICal target;

    public CalProxy(ICal iCal) {
        this.target = iCal;
    }

    public ICal getProxy() {
        ICal proxy = null;
        //类加载器
        ClassLoader loader = target.getClass().getClassLoader();

        //代理对象类型,其中有哪些方法
        Class[] interfaces = new Class[]{ICal.class};

        //调用对象方法时候,该执行代码
        InvocationHandler h = new InvocationHandler() {
            /**
             *
             * @param proxy : 在invoke方法中不使用该对象
             * @param method :正在被调用的方法
             * @param args : 调用方法时候传入的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String name = method.getName();
                System.out.println("Method Name: " + name + " | begin :" + Arrays.asList(args));
                //
                
                Object result = null;
                try{
                    //前置通知 
                    result = method.invoke(target, args);
                    //返回通知,可以返回方法的返回值
                 }catch(Exception e){
                     e.printStackTrace();
                     //异常通知,访问到方法的异常出现
                 }
                 //后置通知,方法可能出现异常,访问不到返回的值
                System.out.println("Method Name: " + name + " | end :" + result);

                return result;
            }
        };
        proxy = (ICal) Proxy.newProxyInstance(loader, interfaces, h);
        return proxy;
    }
}

package aop;


public class Main {

    public static void main(String[] args) {
        ICal target = new CalImpl();
        ICal proxy = new CalProxy(target).getProxy();

        int resultAdd = proxy.add(1 , 2);
        System.out.println("Main : " + resultAdd);


        int resultMul = proxy.mul(3, 4);
        System.out.println("Main : " + resultMul);

    }
}


你可能感兴趣的:(Spring学习笔记十三---动态代理)