【动态代理】

概述

  • 代理模式(proxy pattern):是23种设计模式的一种,属于结构性的模式。指一个对象本身不做实际的操作,而是通过其他对象来得到自己想要的结果。
  • 意义:目标对象只需要关心自己的实现细节,通过代理对象来实现功能的增强,可以扩展目标对象的功能。
  • 体现了非常重要的编程思想:不能随便修改源码,如果需要修改源码,通过修改代理的方式来扩展功能的扩展。

代理的实现方式

  • Java中代理图示
    在这里插入图片描述

  • 元素组成

    • 接口:定义行为和规范的
    • 被代理类,是目标对象
    • 代理类

静态代理

案例

  • 通过代理模式实现事务操作

  • 创建domain对象

/**
 * @Author sima
 * @Date 2023/4/25 18:01
 */
@Data
public class Student {
    private String name;
    private int age;
}

  • 创建service接口定义规范
/**
 * @Author sima
 * @Date 2023/4/25 18:00
 */
public interface IStudentService {

    /**
     * 添加学生
     */
    void save();

    /**
     * 查询学生信息
     * @param id
     * @return
     */
    Student query(Long id);
}

  • 创建实现类(被代理类)
/**
 * @Author sima
 * @Date 2023/4/25 18:05
 */
public class StudentServiceImpl implements IStudentService {
    @Override
    public void save() {
        System.out.println("保存学生信息");
    }

    @Override
    public Student query(Long id) {
        Student student = new Student();
        student.setName("张三");
        student.setAge(18);
        return student;
    }
}

  • 创建事务类对象
/**
 * @Author sima
 * @Date 2023/4/25 18:10
 */
public class DaoTransaction {
    public void before() {
        System.out.println("开启事务");
    }


    public void after() {
        System.out.println("关闭事务");
    }
}
  • 创建代理类对象

/**
 * @Author sima
 * @Date 2023/4/25 18:12
 */
public class ProxyStudent implements IStudentService {
    //目标对象
    private StudentServiceImpl studentService;
    //需要做的增强对象
    private DaoTransaction transaction;

    /**
     * 通过构造器获取目标类和增强类对象
     * @param studentService
     * @param transaction
     */
    public ProxyStudent(StudentServiceImpl studentService,DaoTransaction transaction){
        this.studentService = studentService;
        this.transaction = transaction;
    }
    @Override
    public void save() {
        //开启事务操作
        transaction.before();
        //目标类的操作
        studentService.save();
        //关闭事务操作
        transaction.after();
    }

    @Override
    public Student query(Long id) {
        studentService.query(id);
    }
}
  • 测试方法
import org.junit.Test;

/**
 * @Author sima
 * @Date 2023/4/25 18:19
 */
public class TestStudent {
    /**
     * 保存学生信息
     */
    @Test
    public void testSave(){
        DaoTransaction daoTransaction = new DaoTransaction();
        StudentServiceImpl studentService = new StudentServiceImpl();
        ProxyStudent proxyStudent = new ProxyStudent(studentService, daoTransaction);
        proxyStudent.save();
//        开启事务
//        保存学生信息
//        关闭事务
    }

    /**
     * 查询学生信息
     */
    @Test
    public void testQuery(){
        DaoTransaction daoTransaction = new DaoTransaction();
        StudentServiceImpl studentService = new StudentServiceImpl();
        ProxyStudent proxyStudent = new ProxyStudent(studentService, daoTransaction);
        Student student = proxyStudent.query(1L);
        System.out.println(student);
//        Student(name=张三, age=18)
    }

}

  • 存在问题:
    1.不利于代码的扩展,比如在接口中新添加一个抽箱方法时,所有的实现类都需要重新实现,否则报错。
    2.代理对象需要创建很多,这种设计很不方便。

JDK动态代理

  • 创建service接口

/**
 * @Author sima
 * @Date 2023/4/25 18:00
 */
public interface IStudentService {

    /**
     * 添加学生
     */
    void save();

    /**
     * 查询学生信息
     * @param id
     * @return
     */
    Student query(Long id);
}
  • service实现类(需要代理的类)
/**
 * @Author sima
 * @Date 2023/4/25 18:05
 */
public class StudentServiceImpl implements IStudentService {
    @Override
    public void save() {
        System.out.println("保存学生信息");
    }

    @Override
    public Student query(Long id) {
        Student student = new Student();
        student.setName("张三");
        student.setAge(18);
        return student;
    }
}

  • 实现InvocationHandler接口
    InvocationHandler接口,用来做方法拦截
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author sima
 * @Date 2023/4/25 19:32
 */
public class TranscationHandler implements InvocationHandler {
    //增强类对象
    private DaoTransaction transaction;
    //需要代理的目标对象
    private Object obj;
    public TranscationHandler(DaoTransaction transaction,Object obj){
        this.transaction = transaction;
        this.obj = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object ret = null;
        //判断当前方法是否是save,是才做事务拦截
        if ("save".equals(method.getName())) {
            transaction.before();
            ret = method.invoke(obj,args);
            transaction.after();
        }else{
            ret = method.invoke(obj,args);
        }
        return ret;
    }
}

  • 测试方法
import org.junit.Test;

import java.lang.reflect.Proxy;

/**
 * @Author sima
 * @Date 2023/4/25 18:19
 */
public class TestStudent {
    /**
     * 保存学生信息
     */
    @Test
    public void testSave(){
        //增强类对象
        DaoTransaction daoTransaction = new DaoTransaction();
        //目标执行类
        StudentServiceImpl studentService = new StudentServiceImpl();
        //方法拦截处理器
        TranscationHandler transcationHandler = new TranscationHandler(daoTransaction, studentService);
        //创建代理实例对象
        IStudentService proxyInstance =  (IStudentService)Proxy.newProxyInstance(StudentServiceImpl.class.getClassLoader(), StudentServiceImpl.class.getInterfaces(), transcationHandler);
        proxyInstance.save();

        System.out.println(proxyInstance);
//        开启事务
//        保存学生信息
//        关闭事务
    }
    

}

InvocationHandler invoke里面的参数

proxy:代理实例,可以通过newProxyInstance创建代理实例
Methed:执行目标对象的,invoke方法执行
args:参数数组

Proxy.newProxyInstance 里面的参数

ClassLoader:类加载器
Class<?>[]:目标类实现的所有接口
InvocationHandler:方法拦截处理器,在里面实现方法的加强

源码分析

ublic static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
    	//检查InvocationHandler是否为空,为空抛出空指针异常
        Objects.requireNonNull(h);
		//克隆拿到接口
        final Class<?>[] intfs = interfaces.clone();
        //进行安全校验
        final SecurityManager sm = System.getSecurityManager();
        //检查是否能被代理
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * Look up or generate the designated proxy class.
         * 查找或生成指定的代理类(这一步生成代理对象的class)
         * 这行代码最重要,它可以得到一个代理对象
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         * 使用指定的调用处理程序调用其构造函数。
         * 见下一段代码
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
			//通过类对象获取构造器对象
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            //new得到代理对象
            //获得的代理对象是存这样一个在有参构造
            //将InvocationHandler 通过构造器注入到代理对象中
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

Class<?> cl = getProxyClass0(loader, intfs);

    /**
     * Generate a proxy class.  Must call the checkProxyAccess method
     * to perform permission checks before calling this.
     * 生成代理类。必须调用checkProxyAccess方法以在调用此之前执行权限检查。
     * 
     */
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing 如果由实现的给定加载程序定义的代理类
        // the given interfaces exists, this will simply return the cached copy;如果给定的接口存在,这将简单地返回缓存的副本;
        // otherwise, it will create the proxy class via the ProxyClassFactory否则,它将通过ProxyClassFactory创建代理类
        return proxyClassCache.get(loader, interfaces);
    }

proxyClassCache.get(loader,interfaces)

public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);

        expungeStaleEntries();
		//从缓存中取出代理类的key(classLoader),因为代理类的生成需要耗时间和性能,所有缓存起来方便下次直接使用,
        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey 延迟安装特定cacheKey的第二级值映射
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance 供应商可能是工厂或CacheValue<V>实例
                V value = supplier.get();
                if (value != null) {
                //返回代理类
                    return value;
                }
            }
            // else no supplier in cache 缓存中没有
            // or a supplier that returned null (could be a cleared CacheValue 或返回null的供应商(可能是已清除的CacheValue
            // or a Factory that wasn't successful in installing the CacheValue) 或未成功安装CacheValue的工厂)

            // lazily construct a Factory
            if (factory == null) {
            	通过classLoader 和 接口信息 创建一个工厂
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory 已成功安装工厂
                    //将工厂赋值给supplier
                    //下一次循环调用supplier的git方法 也就是工厂对象的git方法
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    //将工厂赋值给supplier
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

supplier.get():WeakCache.Factory#get()

@Override
        public synchronized V get() { // serialize access
            // re-check
            Supplier<V> supplier = valuesMap.get(subKey);
            if (supplier != this) {
                // something changed while we were waiting:
                // might be that we were replaced by a CacheValue
                // or were removed because of failure ->
                // return null to signal WeakCache.get() to retry
                // the loop
                return null;
            }
            // else still us (supplier == this)

            // create new value
            V value = null;
            try {
            	//key是调构造器传入的new ProxyClassFactory()
            	//执行ProxyClassFactory的apply方法
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) { // remove us on failure
                    valuesMap.remove(subKey, this);
                }
            }
            // the only path to reach here is with non-null value
            assert value != null;

            // wrap value with CacheValue (WeakReference)
            CacheValue<V> cacheValue = new CacheValue<>(value);

            // put into reverseMap
            reverseMap.put(cacheValue, Boolean.TRUE);

            // try replacing us with CacheValue (this should always succeed)
            if (!valuesMap.replace(subKey, this, cacheValue)) {
                throw new AssertionError("Should not reach here");
            }

            // successfully replaced us with new CacheValue -> return the value
            // wrapped by it
            return value;
        }
    }

Proxy.ProxyClassFactory#apply()

@Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
			//获取到所有实现接口
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                	//对接口再次装载,相当classLoader.loadClass
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 * 判断两个接口是不是同一个接口(同一个类加载器加载的):判断对象是否是同一个
                 */
                 
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }
			//代理对象的包名
            String proxyPkg = null;     // package to define proxy class in
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();
                //判断接口的类型是否是public,如果不是public,将代理类放到目标对象同一目录下
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }

            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package (默认定义包名)如果没有非公共代理接口,请使用com.sun.proxy包
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            //标识:private static final String proxyClassNamePrefix = "$Proxy";
            //随机数(防止多线程测试相同的类名):long num = nextUniqueNumber.getAndIncrement();
            //代理类的名字:代理包名+ 标识+ 随机数
          String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class.
             * 生成指定的代理类 生成class 的 byte[]
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
            	//产生代理类,返回一个class:将byte字节码转换成class
                //defineClass0是一个native方法,由JVM实现的:private static native Class<?> defineClass0();

                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }

代理对象的字节码文件


/**
 * @Author sima
 * @Date 2023/4/25 18:19
 */
public class TestStudent {
    /**
     * 保存学生信息
     */
    @Test
    public void testSave() throws IOException {
        //增强类对象
        DaoTransaction daoTransaction = new DaoTransaction();
        //目标执行类
        StudentServiceImpl studentService = new StudentServiceImpl();
        //方法拦截处理器
        TranscationHandler transcationHandler = new TranscationHandler(daoTransaction, studentService);
        //创建代理实例对象
        IStudentService proxyInstance =  (IStudentService)Proxy.newProxyInstance(StudentServiceImpl.class.getClassLoader(),
                StudentServiceImpl.class.getInterfaces(), transcationHandler);
        proxyInstance.save();

//        开启事务
//        保存学生信息
//        关闭事务

        saveProxyClass();
    }


    /**
     * 使用来生成字节码学习使用
     */
    public void saveProxyClass() throws IOException {
        byte[] bytes = ProxyGenerator.generateProxyClass("$proxy1", StudentServiceImpl.class.getInterfaces());
        FileOutputStream fileOutputStream = new FileOutputStream(new File("E:\\$proxy1.class"));
        fileOutputStream.write(bytes);
    }

}

反编译后

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import com.adc.da.JdkProxy.IStudentService;
import com.adc.da.JdkProxy.Student;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
* 通过接口创建的代理类 继承Proxy 实现IStudentService
*/
public final class $proxy1 extends Proxy implements IStudentService {
	// 静态代码块中通过反射得到目标的Method
    private static Method m1;
    private static Method m4;
    private static Method m3;
    private static Method m2;
    private static Method m0;

	//构造方法 在Proxy.newProxyInstance调用该方法实例化,注入自定义的InvocationHandler
    public $proxy1(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final Student query(Long var1) throws  {
        try {
            return (Student)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void save() throws  {
        try {
        	// super.h在构造方法中已赋值,h.invoke真实执行重写的transcationHandler.invoke
        	// invoke 中分别调了增强方法、通过反射调用目标方法。
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("com.adc.da.JdkProxy.IStudentService").getMethod("query", Class.forName("java.lang.Long"));
            m3 = Class.forName("com.adc.da.JdkProxy.IStudentService").getMethod("save");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

Cglib 动态代理

  • 实现方法拦截MethodInterceprot

/**
 * @Author sima
 * @Date 2023/4/26 8:00
 */
public class CglibInterceptor implements MethodInterceptor {
    DaoTransaction transaction;

    public CglibInterceptor(DaoTransaction transaction){
        this.transaction = transaction;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // 事务增强
        transaction.before();
        // 目标方法
        methodProxy.invokeSuper(o,objects);
        transaction.after();
        return null;
    }
}

  • 测试代码
/**
 * @Author sima
 * @Date 2023/4/25 18:19
 */
public class TestStudent {
    /**
     * 保存学生信息
     */
    @Test
    public void testSave() throws IOException {
    	//生成目标代理类
       System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"E:\\");
        //得到方法拦截器
        CglibInterceptor cglibInterceptor = new CglibInterceptor(new DaoTransaction());
        //使用CGLIB框架生成目标类的字类(代理类)
        Enhancer enhancer = new Enhancer();
        //设置父类字节码
        enhancer.setSuperclass(StudentServiceImpl.class);
        //设置拦截处理器
        enhancer.setCallback(cglibInterceptor);
        IStudentService studentService = (IStudentService)enhancer.create();
        studentService.save();
//        开启事务
//        保存学生信息
//        关闭事务

    }

}
  • 代理类反编译

import java.lang.reflect.Method;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
* 继承目标类
*/
public class StudentServiceImpl$$EnhancerByCGLIB$$f83062aa extends StudentServiceImpl implements Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static Object CGLIB$CALLBACK_FILTER;
    private static final Method CGLIB$save$0$Method;
    private static final MethodProxy CGLIB$save$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$query$1$Method;
    private static final MethodProxy CGLIB$query$1$Proxy;
    private static final Method CGLIB$equals$2$Method;
    private static final MethodProxy CGLIB$equals$2$Proxy;
    private static final Method CGLIB$toString$3$Method;
    private static final MethodProxy CGLIB$toString$3$Proxy;
    private static final Method CGLIB$hashCode$4$Method;
    private static final MethodProxy CGLIB$hashCode$4$Proxy;
    private static final Method CGLIB$clone$5$Method;
    private static final MethodProxy CGLIB$clone$5$Proxy;

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.adc.da.cglib.StudentServiceImpl$$EnhancerByCGLIB$$f83062aa");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"save", "()V", "query", "(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;"}, (var1 = Class.forName("com.adc.da.cglib.StudentServiceImpl")).getDeclaredMethods());
        CGLIB$save$0$Method = var10000[0];
        CGLIB$save$0$Proxy = MethodProxy.create(var1, var0, "()V", "save", "CGLIB$save$0");
        CGLIB$query$1$Method = var10000[1];
        CGLIB$query$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;", "query", "CGLIB$query$1");
        var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$equals$2$Method = var10000[0];
        CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
        CGLIB$toString$3$Method = var10000[1];
        CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
        CGLIB$hashCode$4$Method = var10000[2];
        CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");
        CGLIB$clone$5$Method = var10000[3];
        CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
    }

    final void CGLIB$save$0() {
        super.save();
    }

    public final void save() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
        	// 执行MehodIntercept的方法
            var10000.intercept(this, CGLIB$save$0$Method, CGLIB$emptyArgs, CGLIB$save$0$Proxy);
        } else {
            super.save();
        }
    }

    final Student CGLIB$query$1(Long var1) {
        return super.query(var1);
    }

    public final Student query(Long var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (Student)var10000.intercept(this, CGLIB$query$1$Method, new Object[]{var1}, CGLIB$query$1$Proxy) : super.query(var1);
    }

    final boolean CGLIB$equals$2(Object var1) {
        return super.equals(var1);
    }

    public final boolean equals(Object var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            Object var2 = var10000.intercept(this, CGLIB$equals$2$Method, new Object[]{var1}, CGLIB$equals$2$Proxy);
            return var2 == null ? false : (Boolean)var2;
        } else {
            return super.equals(var1);
        }
    }

    final String CGLIB$toString$3() {
        return super.toString();
    }

    public final String toString() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy) : super.toString();
    }

    final int CGLIB$hashCode$4() {
        return super.hashCode();
    }

    public final int hashCode() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            Object var1 = var10000.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
            return var1 == null ? 0 : ((Number)var1).intValue();
        } else {
            return super.hashCode();
        }
    }

    final Object CGLIB$clone$5() throws CloneNotSupportedException {
        return super.clone();
    }

    protected final Object clone() throws CloneNotSupportedException {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? var10000.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
    }

    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return CGLIB$clone$5$Proxy;
            }
            break;
        case -34064223:
            if (var10000.equals("query(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;")) {
                return CGLIB$query$1$Proxy;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return CGLIB$equals$2$Proxy;
            }
            break;
        case 1872760024:
            if (var10000.equals("save()V")) {
                return CGLIB$save$0$Proxy;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return CGLIB$toString$3$Proxy;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return CGLIB$hashCode$4$Proxy;
            }
        }

        return null;
    }

    public StudentServiceImpl$$EnhancerByCGLIB$$f83062aa() {
        CGLIB$BIND_CALLBACKS(this);
    }

    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }

    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }

    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var1 = (StudentServiceImpl$$EnhancerByCGLIB$$f83062aa)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (var10000 == null) {
                    return;
                }
            }

            var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
        }

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
        StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa;
        switch(var1.length) {
        case 0:
            var10000.<init>();
            CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
            return var10000;
        default:
            throw new IllegalArgumentException("Constructor not found");
        }
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        MethodInterceptor var10000;
        switch(var1) {
        case 0:
            var10000 = this.CGLIB$CALLBACK_0;
            break;
        default:
            var10000 = null;
        }

        return var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
        default:
        }
    }

    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0};
    }

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
    }

    static {
        CGLIB$STATICHOOK1();
    }
}

总结

  • JDK动态代理有一个前提,需要代理的类必须实现接口,如果没有实现接口,只能通过CGLIB来实现,其实就是对JDK动态代理的一个补充。
  • 使用CGLIB 代理,类不能被final 修饰,方法不能被final 修饰,因为不能继承,重写。
代理类型实现机制回调方式使用场景
JDK动态代理通过实现接口,通过反射机制获取到接口里面的方法,并且自定义InvocationHandler接口,实现方法拦截调用invoke方法实现增强目标类有接口
CGLIB动态代理继承机制,通过继承重写目标方法,使用MethodInterceptor 调用父类的目标方法从而实现代理调用MethodInterceptor中 interceptor方法不用final修饰的类和方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值