CGLIB 动态代理

目录

CGLIB 动态代理

简单结构:

添加依赖

定义类


CGLIB 动态代理

        JDK的动态代理机制只能代理实现了接口的类。而不能实现接口的类就不能使用JDK的动态代理,CGLIB是针对类来实现代理的,它的原理是对指定目标类生成一个子类,并覆盖其中的方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

简单结构:

        实现原理:继承思想

代理类继承目标类,重写目标类中的方法,

        CGLIB像是一个拦截器,在调用我们的代理类方法时,代理类(子类)会去找到目标类(父类),此时它会被一个方法拦截器所拦截,在拦截器中才会去实现方法的调用。并且还会对方法进行行为增强。

CGLIB 动态代理_第1张图片

简单实现

添加依赖

在pom.xml文件中引入CGLIB的相关依赖





cglib

cglib

3.3.0

定义类

实现MethodInterceptor接口

​
package org.example.proxy;

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 Cglib implements MethodInterceptor {
    //准备一个目标对象
    private Object target;
    //通过构造器传入目标对象
    public Cglib(Object target) {
        this.target = target;
    }
    /*
    * 用来获取代理对象(创建一个代理对象)
    * */
    public Object getProxy(){
        //可以通过Enhancer对象中的create()方法可以去生成一个类,用于生成代理对象
        Enhancer enhancer=new Enhancer();
        //设置父类(将目标类作为代理类的父类)
        enhancer.setSuperclass(target.getClass());
        //设置拦截器(回调对象为本身对象)
        enhancer.setCallback(this);
        //生成一个代理类对象并返回给调用着
        return enhancer.create();
    }
    /*
    * 拦截器
    *       1.目标对象的方法调用
    *       2.行为增强
    *      参数 o: cglib 动态生成的代理类的实例
    *          method:实体类所调用的都被代理的方法的引用
    *          objects 参数列表
    *          methodProxy:生成的代理类对方法的代理引用
    * */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //增强行为
        System.out.println("方法执行前的增强行为");
        //调用目标类中的方法
        Object Objectss=  methodProxy.invoke(target,objects);
        //增强行为
        System.out.println("方法执行后的增强行为");
        return null;
    }
}

​

定义一个test()类

package org.example.proxy;

public class test3 {
    public static void main(String[] args) {
        //得到目标对象
        You you=new You();
        //得到代理类
        Cglib cglib=new Cglib(you);
        //得到代理对象
        Marry marry= (Marry) cglib.getProxy();
        //通过代理对象调用目标对象的方法
        marry.toMarry();
    }
}

CGLIB 动态代理_第2张图片

 

 那我们来了解一下CGLIB的实现流程

                我们最终是要通过一个代理对象去调用方法的,那我们就要获取一个代理对象,

CGLIB代理,是通过Enhancer这个类里面对应的一个create()方法,去生成一个代理对象的。

那么咱们就先创建一个Enhancer对象,拿到这个对象之后,虽然我们是要获取一个代理对象,但你要获取谁的代理对象?咱们是不是要知道。而前面提到CGLIB体现的是继承思想,所以我们需要把代理类作为我们目标类的一个子类,也就是把目标类设置为父类,代理类去继承它。

 //设置父类(将目标类作为代理类的父类)
        enhancer.setSuperclass(target.getClass());
      在你获取代理对象之前,我们应该知道目标对象是谁吧?  

获取目标对象,我们还是通过带参构造传进来的。

 //准备一个目标对象
    private Object target;
    //通过构造器传入目标对象
    public Cglib(Object target) {
        this.target = target;
    }
目标对象有了,通过Enhancer代理对象也有了。那么我们创建的类为什么要实现MethodInterceptor接口?

在上图中我们说过会有一个拦截器,MethodInterceptor就是起到的一个拦截作用,在你调用目标类的方法后,它就会被我们的一个拦截器所拦截。

        实现MethodInterceptor接口就必须重写intercept方法

 /*
    * 拦截器
    *       1.目标对象的方法调用
    *       2.行为增强
    *      参数 o: cglib 动态生成的代理类的实例
    *          method:实体类所调用的都被代理的方法的引用
    *          objects 参数列表
    *          methodProxy:生成的代理类对方法的代理引用
    * */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //增强行为
        System.out.println("方法执行前的增强行为");
        //调用目标类中的方法
        Object Objectss=  methodProxy.invoke(target,objects);
        //增强行为
        System.out.println("方法执行后的增强行为");
        return Objectss;
    }

在intercept方法中我们用methodProxy.invoke(参1,参2);调用目标类中的方法。两个参数分别为目标对象,方法中的参数


JDK代理与CGLIB代理的区别

  • JDK动态代理实现接口,CGLIB动态继承思想
  • JDK动态代理(目标对象存在接口时)执行效率高于CIGLIB
  • 如果对象有接口实现,选择JDK代理,如果没有接口实现选择CGILB代理

你可能感兴趣的:(笔记,代理模式)