JAVA Basics--Dynamic Proxy

The role of dynamic proxy: to achieve method enhancement without modifying the source code.
Dynamic code:

  • Features: Bytecode can be created and loaded whenever it is used
  • Function: Add functions to the method without changing the source code Category
    :
  • Interface-based dynamic proxy
  • Subclass-based dynamic proxies

Interface-based dynamic proxy

Interface-based dynamic proxy:

  • Class involved: Proxy
  • Provider: JDK official
  • How to create a proxy object:
    •   使用Proxy中的newProxyInstance方法
      
  • Requirements for creating proxy objects:
    • 被代理类至少实现一个接口,如果没有则不能创建
      
  • Parameters of the newProxyInstance method:
    •   ClassLoader: 类加载器
      
    •       它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器
      
  • class[]: bytecode array
    •       它是让代理对象和被代理对象有相同的方法
      
  • InvocationHandler: used to provide enhanced code
    •       它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
      
    •       此接口的实现类都是谁用谁写。
      

Create Iproduct interface

public interface Iprodouct {
    
    
    public void saleComputer(Float money);
    public void afterSale(Float money);
}

Create an implementation class distribute

public class distributor implements Iprodouct {
    
    
    @Override
    public void saleComputer(Float money) {
    
    
        System.out.println("卖出去了一台电脑:" + money);
    }

    @Override
    public void afterSale(Float money) {
    
    
        System.out.println("经过售后赚了:" + money);
    }
}

Create user tests

public class client {
    
    
    public static void main(String[] args) {
    
    
        distributor distributor = new distributor();


      
        Iprodouct proxyProdouce = (Iprodouct) Proxy.newProxyInstance(distributor.getClass().getClassLoader(),
                distributor.getClass().getInterfaces(),
                new InvocationHandler() {
    
    
                    /**
                     * 作用:执行被代理对象的任何接口方法都会经过该方法
                     * 方法参数的含义
                     * @param proxy   代理对象的引用
                     * @param method  当前执行的方法
                     * @param args    当前执行方法所需的参数
                     * @return 和被代理对象方法有相同的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
                        // 提供增强的代码
                        Object returnValue = null;
                        // 1、获取代码执行的参数
                        Float money = (Float)args[0];
                        // 2、判断当前方法是否是销售
                        if ("saleComputer".equals(method.getName())) {
    
    
                            returnValue = method.invoke(distributor, money*0.8f);
                        }
                        return returnValue;
                    }
                });
        proxyProdouce.saleComputer(10000f);
    }
}

Subclass-based dynamic proxies

  • Class involved: Enhancer
    •   提供者:cglib第三方
      
  • How to create a proxy object:
    •   使用Enhancer中的create方法
      
  • Requirements for creating proxy objects:
    •   被代理类不能是最终类
      
  • The parameters of the create method:
    •   Class:字节码
      
    •      它是用于指定被代理对象的字节码。
      
  • Callback: used to provide enhanced code
    •      它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
      
    •      此接口的实现类都是谁用谁写。
      
    •      我们一般写的都是该接口的子接口实现类:MethodInterceptor
      

Create the distribute class

public class distributor{
    
    

    public void saleComputer(Float money) {
    
    
        System.out.println("卖出去了一台电脑:" + money);
    }


    public void afterSale(Float money) {
    
    
        System.out.println("经过售后赚了:" + money);
    }
}

implement test

public class clientCglib {
    
    
    public static void main(String[] args) {
    
    
        distributor distributor = new distributor();

        distributor dis = (distributor) Enhancer.create(distributor.getClass(), new MethodInterceptor() {
    
    
            /**
             *
             * @param o             增强对象
             * @param method        增强的方法
             * @param objects       参数值
             * @param methodProxy   当前执行方法的执行对象
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
                // 提供增强的代码
                Object returnValue = null;
                // 1、获取代码执行的参数
                System.out.println(objects[0]);
                Float money = (Float) objects[0];
                // 2、判断当前方法是否是销售
                if ("saleComputer".equals(method.getName())) {
    
    
                    returnValue = method.invoke(distributor, money * 0.8f);
                }
                return returnValue;
            }
        });
        dis.saleComputer(1000f);
    }
}

Guess you like

Origin blog.csdn.net/qq_44660367/article/details/108214660