详解 java中 动态代理的两种实现方式(具体案例分析)

一. 简介

代理这种模式其实就是在不改变目标对象方法的情况下对方法进行增强
  本文将从基于接口以及基于子类的方式来讲解动态代理

二. 基于接口的动态代理

核心:

  JDK官方提供的Proxy类中的newProxyInstance方法

案例分析:

在这里插入图片描述

这就是需要方法增强的生产者

public class Producer implements IProducer {
    
    
    public void saleProduct(Float money){
    
    
        System.out.println("销售产品,并拿到钱:"+ money);
    }


    public  void afterService(Float money){
    
    
        System.out.println("提供售后,并拿到钱:"+money);
    }
}

使用Proxy类中的newProxyInstance()进行方法的增强

                 * 作用:执行被代理对象的任何接口方法都会经过该方法
                 * 方法参数的含义
                 * @param proxy   代理对象的引用
                 * @param method  当前执行的方法
                 * @param args    当前执行方法所需的参数
                 * @return        和被代理对象方法有相同的返回值
                 * @throws Throwable
                 */
public static void main(String[] args) {
    
    
         final IProducer producer = new Producer();
        IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                producer.getClass().getInterfaces(),
                new InvocationHandler() {
    
    

                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
                        //提供增强的代码
                        Object returnValue = null;

                        //1.获取方法执行的参数
                        Float money = (Float)args[0];
                        //2.判断当前方法是不是销售
                        if("saleProduct".equals(method.getName())) {
    
    
                            returnValue = method.invoke(producer, money*0.8f);
                        }
                        return returnValue;

                    }
                });
}

案例的理解:

因为要对接口中的方法增强,所以使用newProxyInstance来创建代理对象

  调用接口中的方法,都将会经过invoke方法

  invoke方法就是负责方法的增强

三. 基于子类的动态代理

核心:

cglib提供的Enhancer类中的create方法
注:需要导入cglib的依赖
在这里插入图片描述

扫描二维码关注公众号,回复: 17075148 查看本文章

案例分析:

在这里插入图片描述

同上个案例一样,这也是需要增强的方法

public class Producer  {
    
    
    public void saleProduct(Float money){
    
    
        System.out.println("销售产品,并拿到钱:"+ money);
    }


    public  void afterService(Float money){
    
    
        System.out.println("提供售后,并拿到钱:"+money);
    }
}

使用cglib中的create()进行方法的增强

		 * 执行被代理对象的任何方法都会经过该方法
         * @param proxy
         * @param method
         * @param args
         *  以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
         * @param methodProxy :当前执行方法的代理对象
         * @return
         * @throws Throwable
public class Client {
    
    
    public static void main(String[] args) {
    
    
        final Producer producer = new Producer();
        Producer cglibPro = (Producer) Enhancer.create(Producer.class, new MethodInterceptor() {
    
    
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    
    
                //提供增强的代码
                Object returnValue = null;

                //1.获取方法执行的参数
                Float money = (Float)args[0];
                //2.判断当前方法是不是销售
                if("saleProduct".equals(method.getName())) {
    
    
                    returnValue = method.invoke(producer, money*0.8f);
                }
                return returnValue;
            }
        });
}

案例的理解:

使用 Enhancer.create来创建代理对象

  调用接口中的方法,都将会经过intercept方法

  intercept方法就是负责方法的增强

四. 总结:

两种方式的动态代理的代码逻辑都是差不多的

  1. 创建代理对象
  2. 获取当前方法的参数
  3. 使用方法名判断是否是某个特定方法
  4. 执行method.invoke方法
  5. 使用你所创建出来的代理对象

猜你喜欢

转载自blog.csdn.net/qq_44716086/article/details/105922288