静态代理

动态代理

1:CGLib的基本介绍

2:目标类

3:方法拦截器

4:测试类


 

静态代理

这里我们介绍了静态代理,也知道了静态代理的一些缺点
代理模式-静态代理

下面我们就介绍动态代理(基于继承,cglib动态代理)

动态代理

1:CGLib的基本介绍

看一下CGLib的基本结构,下图所示,代理类去继承目标类,每次调用代理类的方法都会被方法拦截器拦截,在拦截器中才是调用目标类的该方法的逻辑,结构还是一目了然的; 

 

代理模式-动态代理(基于继承,cglib动态代理)_设计模式

使用一下CGLib,在JDK动态代理中提供一个Proxy类来创建代理类,而在CGLib动态代理中也提供了一个类似的类Enhancer;

使用的CGLib版本是3.3.0,我用的maven项目进行测试的,首先要导入cglib的依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

 

2:目标类

目标类(一个公开方法,打lol,另外一个用final修饰,学习):

package com.lingaolu.bean;

/**
 * @author 林高禄
 * @create 2020-11-09-10:30
 */
public class Me {

    public String lol() {
        System.out.println("登录账号:林高禄");
        /*
         * 排位,组队
         * 补刀,抓人,打团。提高意识......等一系列操作
         */
        return "铂金2";
    }

    final public void study(){
        System.out.println("写博客");
    }

}

 

3:方法拦截器

package com.lingaolu.service;

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

import java.lang.reflect.Method;

/**
 * @author 林高禄
 * @create 2020-11-09-23:13
 */
public class MyMethodInterceptor  implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("这里是对目标类进行增强!!!");
        //注意这里的方法调用,不是用反射哦!!!
        Object object = proxy.invokeSuper(obj, args);
        return object;
    }
}

 

4:测试类

package com.lingaolu;

import com.lingaolu.bean.Me;
import com.lingaolu.service.MyMethodInterceptor;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
import org.junit.Test;

/**
 * @author 林高禄
 * @create 2020-11-03-9:22
 */
public class TestDemo {

    @Test
    public void testProxy(){
        // 在指定目录下生成动态代理类,我们可以反编译看一下里面到底是一些什么东西
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\java\\java_workapace");

        // 创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数
        Enhancer enhancer = new Enhancer();
        // 设置目标类的字节码文件
        enhancer.setSuperclass(Me.class);
        // 设置回调函数
        enhancer.setCallback(new MyMethodInterceptor());

        // 这里的creat方法就是正式创建代理类
        Me proxyMe = (Me)enhancer.create();
        // 调用代理类的lol方法
        proxyMe.lol();
        // 分隔符
        System.out.println("------------------------------");
        // 调用代理类的study方法
        proxyMe.study();
    }
}

 

代理模式-动态代理(基于继承,cglib动态代理)_设计模式_02

这里只介绍如何使用,至于原理,可以参考这篇

CGLib动态代理