基于接口的动态代理和基于子类的动态代理,只需要这一篇就够了,动态代理的实现 什么是动态代理 Java

Study

动态代理分析

功能

  • 特点: 字节码可以随用随创建,随用随加载
  • 作用: 不写该源码的基础上对方法增强
  • 分类:
    • 基于接口的动态代理
    • 基于子类的动态代理
基于接口的动态代理
  • 类: Proxy
  • 提供者JDK
  • 如何创建代理对象?
    • 使用Proxy类中的++newProxyInstance++方法
  • 创建被代理对象的要求:
    • 被代理类至少要实现一个接口,如果没有则不能使用
  • newProxyInstance方法的参数
    • classLoader
      • 用于加载代理对象字节码的,和被代理对象使用相同的类加载器。
    • Class[]
      • 让代理对象和被代理对象有相同的方法。(两个同一实现一个接口)
    • InvocationHandler:对方增强
      • 如何代理:通常采用匿名内部类。
Iprodcer o = (Iprodcer)Proxy.newProxyInstance(prodcer.getClass().getClassLoader(), prodcer.getClass().getInterfaces(),
            new InvocationHandler() {
                /**
                 * 执行被代理对象的任何接口方法都会经过次方法
                 * @param proxy:代理对象的引用
                 * @param method:调用的方法
                 * @param args:方法参数
                 * @return: 和原方法一致返回值
                 * @throws Throwable
                 */
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if(method.getName().equals("saleProduct")){
                        return method.invoke(prodcer, (Double)args[0]*0.8);
                    }
                    return null;
                }
            });

基于子类的动态代理
  • 类: ++Enhancer++
  • 第三方
  • 如何创建代理对象?
    • 使用Enhancer类中的++create++方法
  • 创建被代理对象的要求:
    • 被代理类不能是最终类,如果没有则不能使用
  • create方法的参数
    • Class
      • 用于加载代理对象字节码的,和被代理对象使用相同的类加载器。
    • CallBack:增强
      • 一般写的子接口的实现类:++MthodIntercepter++
1. 引入cglib
    <dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.1_3</version>
        </dependency>
    </dependencies>
2. 创建被代理类
package com.atjianyi.da;

/**
 * @author 简一
 * @className Producer
 * @Date 2021/1/26 14:17
 **/
public class Producer {
    public void salerProduct(double money){
        System.out.println("销售了+"+money);
    }
}

3. 创建代理对象并调用执行
public static void main(final String[] args) {
        //创建被代理类的对象
        final Producer producer = new Producer();

        Producer cglibPro = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                //判断方法
                double money = (Double) objects[0];
                if ("salerProduct".equals(method.getName())) {
                    return method.invoke(producer, money* 0.8);
                }
                return null;
            }
        });
        cglibPro.salerProduct(1000);
    }

猜你喜欢

转载自blog.csdn.net/Janyi_/article/details/113179668