代理模式之Cglib动态代理

在这里插入图片描述

<!-- cglib代码生成类库,基于Java字节码操作框架ASM生成代码 -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>
package com_.dxy_test_.cglib_proxy_;

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

import java.lang.reflect.Method;

/**
 * @Description Cglib类库动态代理测试
 * @Author dangxianyue
 * @Date 2022/9/25 12:37
 */
public class CglibDynamicProxyTest {

    public static void main(String[] args) {
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");
        //创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数
        Enhancer enhancer = new Enhancer();
        //设置代理类的要继承的类
        enhancer.setSuperclass(Suitor.class);
        //设置回调函数
        enhancer.setCallback(new ProxyEnhancer(new Suitor()));
        //创建代理类
        Suitor _proxy = (Suitor) enhancer.create();
        System.out.println("_proxy_super_class: " + _proxy.getClass().getSuperclass().getName());
        //_proxy: com.bzyd.test.cglib_proxy_.Suitor
        //cglib的代理类为被代理类的子类,这点是和JDK代理的区别
        _proxy.sendLetter("小丽");

        System.out.println("\n\n调用final、static方法测试是否会被代理:");
        _proxy.finalMethod();
        Suitor.staticMethod();
    }

}

/**
 * 追求者,被代理者
 */
class Suitor {

    /**
     * 写情书
     *
     * @param name
     */
    public void writeLetter(String name) {
        System.out.println("写情书:" + name + ",我喜欢你!");
    }

    /**
     * 送情书
     *
     * @param name
     */
    public void sendLetter(String name) {
        //注意和JDK不同之处:
        //Cglib代理是子类继承的方式,即代理类是被代理类的子类
        //若类内调用的方法是private的,则不回被继承,也就不会被代理增强,反之则可以
        //但这里是用原生写法是这样,若Spring AOP中Cglib代理又不一样,类内调用都不能被代理增强
        writeLetter(name);
        System.out.println("送情书:" + name + ",这是有人送你的情书!");
    }

    /**
     * 测试final方法是否会被代理
     */
    public final void finalMethod() {
        System.out.println("final method");
    }

    /**
     * 测试static方法是否会被代理
     */
    public static void staticMethod() {
        System.out.println("static method");
    }

}

/**
 * 代理增强类
 * 封装增强逻辑
 * 实现net.sf.cglib.proxy.MethodInterceptor
 * 相当于JDK代理中的InvocationHandler
 */
class ProxyEnhancer implements MethodInterceptor {

    private Suitor suitor;

    public ProxyEnhancer() {
    }

    public ProxyEnhancer(Suitor suitor) {
        this.suitor = suitor;
    }

    /**
     * 封装增强逻辑
     *
     * @param o           代理对象
     * @param method      被代理对象的方法
     * @param objects     方法入参
     * @param methodProxy 代理方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        String s = "writeLetter".equals(method.getName()) ? "写情书" :
                ("sendLetter".equals(method.getName()) ? "送情书" : "");
        System.out.println("增强逻辑【" + s + "】>>>>>>>>>>>>>开始");

        //1、使用methodProxy.invokeSuper,是Cglib中提供的反射,反射的实例是代理对象,即被代理者的子类
        //所以类内调用public方法也会被代理增强
//        Object invoke = methodProxy.invokeSuper(o, objects);

        //2、使用method.invoke是Java的原生反射,反射的实例直接是被代理者,
        //所以类内方法间调用都是调用被代者中的方法,不会被代理增强,Spring AOP中的Cglib就是这种方式
        Object invoke = method.invoke(suitor, objects);
        System.out.println("增强逻辑【" + s + "】>>>>>>>>>>>>>结束");
        return invoke;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex·Guangzhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值