Spring_dynamic proxy_hehe.employment.over.35.1

Article Directory

35.1 Dynamic Proxy

  • Features: Bytecode is created as you use it, and loaded as you use it
  • Function: Enhance the method without modifying the source code
  • classification:
    • Dynamic proxy based on interface
      • Involved class: Proxy
      • Provider: JDK official
      • How to create a proxy object:
        • Use the newProxyInstance method in the Proxy class
      • Requirements for creating proxy objects:
        • The proxy class implements at least one interface, if not, it cannot be used
      • Parameters of the newProxyInstance method:
        • ClassLoader : class loader
          • It is used to load the proxy object bytecode. Use the same class loader as the proxy object. Fixed writing.
        • ***Class[]***: bytecode array
          • It is used to make the proxy object and the proxy object have the same method. Fixed writing.
        • InvocationHandler : used to provide enhanced code
          • It is let us write how to proxy. We are generally an implementation class of this interface, usually anonymous inner classes, but it is not necessary.
          • The implementation class of this interface is written by whoever uses it.
package com.itheima.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 模拟一个消费者
 */
public class Client {
    
    

    public static void main(String[] args) {
    
    
        final Producer producer = new Producer();
       IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                producer.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("saleProduct".equals(method.getName())) {
    
    
                            returnValue = method.invoke(producer, money*0.8f);
                        }
                        return returnValue;
                    }
                });
        proxyProducer.saleProduct(10000f);
    }
}

  • Dynamic proxy based on subclasses:
    • Involved class : Enhancer
    • Provider : third-party cglib library
  • How to create a proxy object:
    • Use the create method in the Enhancer class
  • Requirements for creating proxy objects:
    • The proxy class cannot be the final class
  • Parameters of the create method:
    • Class : Bytecode, it is the bytecode used to specify the proxy object.
    • Callback : used to provide enhanced code
      • It is let us write how to proxy. We are generally an implementation class of this interface, usually anonymous inner classes, but it is not necessary.
      • The implementation class of this interface is written by whoever uses it.
      • We generally write the sub-interface implementation class of this interface: MethodInterceptor
package com.itheima.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 模拟一个消费者
 */
public class Client {
    
    

    public static void main(String[] args) {
    
    
        final Producer producer = new Producer();
        Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
    
    
            /**
             * 执行北地阿里对象的任何方法都会经过该方法
             * @param proxy
             * @param method
             * @param args
             *    以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
             * @param methodProxy :当前执行方法的代理对象
             * @return
             * @throws Throwable
             */
            @Override
            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;
            }
        });
        cglibProducer.saleProduct(12000f);
    }
}

Guess you like

Origin blog.csdn.net/qq_44686266/article/details/114653890