Spring MVC 中的 AOP(动态代理)-个人总结

动态代理主要有两种实现方式:JDK动态代理和CGLIB动态代理。

  1. JDK动态代理:是基于Java反射机制实现的,只能代理实现了接口的类。方法拦截器实现InvocationHandler接口。

    /**
    首先我们定义一个接口Service与它的实现类
    */
    // 目标接口 
    interface Service {
        void performTask();
        void anotherTask();
    }
    ​
    // 目标类实现接口
    class ServiceImpl implements Service {
        @Override
        public void performTask() {
            System.out.println("Executing task in ServiceImpl");
        }
    ​
        @Override
        public void anotherTask() {
            System.out.println("Executing another task in ServiceImpl");
        }
    }
    /**
    创建实现InvocationHandler接口的代理类
    */
    // 动态代理类
    class ServiceInvocationHandler implements InvocationHandler {
        private final Service target; // 目标对象
    ​
        // 构造函数接受目标对象
        public ServiceInvocationHandler(Service target) {
            this.target = target;
        }
    ​
        // 代理对象的方法被调用时,invoke 方法会被执行
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 在调用目标方法前添加逻辑
            System.out.println("Before executing " + method.getName());
            
            // 通过反射调用目标对象的方法
            Object result = method.invoke(target, args);
    ​
            // 在调用目标方法后添加逻辑
            System.out.println("After executing " + method.getName());
            
            return result;
        }
    }
    /**
    创建代理对象
    */
    public class Main {
        public static void main(String[] args) {
            // 创建目标对象
            Service target = new ServiceImpl();
    ​
            // 通过 Proxy 类生成代理对象
            Service proxyInstance = (Service) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  // 类加载器
                target.getClass().getInterfaces(),   // 目标对象实现的接口
                new ServiceInvocationHandler(target) // InvocationHandler 的实现
            );
    ​
            // 调用代理对象的方法
            proxyInstance.performTask();
            proxyInstance.anotherTask();
        }
    }
    // 运行结果
    Before executing performTask
    Executing task in ServiceImpl
    After executing performTask
    Before executing anotherTask
    Executing another task in ServiceImpl
    After executing anotherTask

     

  2. CGLIB动态代理:可以为没有实现接口的类创建代理,通过生成目标代理类的子类来实现代理。方法拦截器实现MethodInterceptor接口。

    // 目标类:需要被代理的类
    class Service {
        public void performTask() {
            System.out.println("Executing task in Service");
        }
    ​
        public void anotherTask() {
            System.out.println("Executing another task in Service");
        }
    }
    // 方法拦截器:通过这个接口可以拦截目标类的方法调用。
    ​
    class ServiceMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            // 在方法执行前添加逻辑
            System.out.println("Before executing " + method.getName());
            
            // 调用父类(即目标类)的原始方法
            Object result = proxy.invokeSuper(obj, args);
    ​
            // 在方法执行后添加逻辑
            System.out.println("After executing " + method.getName());
            
            return result;
        }
    }
    // 动态代理的实现:使用 CGLIB 的 Enhancer 类来创建目标类的代理对象。
    import net.sf.cglib.proxy.Enhancer;
    ​
    public class Main {
        public static void main(String[] args) {
            // 创建Enhancer对象,类似于代理的构建器
            Enhancer enhancer = new Enhancer();
            
            // 设置父类为目标类,即Service类
            enhancer.setSuperclass(Service.class);
            
            // 设置回调接口,即MethodInterceptor的实现
            enhancer.setCallback(new ServiceMethodInterceptor());
    ​
            // 创建代理对象,这个代理对象是Service类的子类
            Service proxy = (Service) enhancer.create();
            
            // 调用代理对象的方法
            proxy.performTask();
            proxy.anotherTask();
        }
    }
    // 运行结果
    Before executing performTask
    Executing task in Service
    After executing performTask
    Before executing anotherTask
    Executing another task in Service
    After executing anotherTask

    总结:

    JDK动态代理:一个类没有实现则无法使用JDK动态代理。

    CGLIB动态代理:可以为没有实现接口的类创建代理。CGLIB动态代理不可以代理被final修饰的类,这也是他的限制。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值