CGLIB动态代理(AOP原理)(面试重点)

推荐先看JDK 动态代理(Spring AOP 的原理)(面试重点)

JDK 动态代理与 CGLIB 动态代理的区别

JDK 动态代理有⼀个最致命的问题是其只能代理实现了接⼝的类.

有些场景下,我们的业务代码是直接实现的,并没有接⼝定义.为了解决这个问题,我们可以⽤CGLIB 动态代理机制来解决.

CGLIB(Code Generation Library)是⼀个基于ASM的字节码⽣成库,它允许我们在运⾏时对字节码进⾏ 修改和动态⽣成. CGLIB 通过继承⽅式实现代理, 很多知名的开源框架都使⽤到了CGLIB.例如 Spring 中的 AOP 模块中: 如果⽬标对象实现了接⼝,则默认采⽤ JDK 动态代理, 否则采⽤ CGLIB 动态代理.

CGLIB 动态代理类实现步骤

1.添加依赖

和 JDK 动态代理不同, CGLIB(Code Generation Library) 实际是属于⼀个开源项⽬,如果你要使⽤它的话,需要⼿动添加相关依赖

java 复制代码
<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>3.3.0</version>
</dependency>

2. 定义⼀个类(被代理类 -> 目标类)

目标类实现的接口 :

java 复制代码
//声明房东(目标对象)要执行的相关操作
public interface HouseSubject {
    void rentHouse();   //出租房子
    void saleHouse();   //卖房子
}

目标类:

java 复制代码
public class Landlord implements HouseSubject{
    @Override
    public void rentHouse() {
        System.out.println("房东出租房子");
    }

    @Override
    public void saleHouse() {
        System.out.println("房东卖房子");
    }
}

3. ⾃定义 MethodInterceptor 并重写 intercept ⽅法, intercept ⽤于增强⽬标⽅法,和 JDK 动态代理中的 invoke ⽅法类似(写代理对象的逻辑)

java 复制代码
// CGLIB 动态代理的逻辑
public class CGLIBDynamicProxy implements MethodInterceptor {
    private Object target;

    public CGLIBDynamicProxy(Object target){
        this.target=target;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //动态代理的逻辑
        System.out.println("代理接手,工作开始");
        //执行目标对象中的操作
        Object result=methodProxy.invoke(target,objects);
        System.out.println("代理离手,工作结束");
        return result;
    }
}

4. 通过 Enhancer 类的 create() 创建并使用代理类

java 复制代码
//创建代理对象并使用
public class DynamicMain {
    public static void main(String[] args) {

        HouseSubject target=new Landlord();
        Landlord target1=new Landlord();

        //通过 CGLIB 创建代理对象
        HouseSubject proxy1= (HouseSubject) Enhancer.create(
                target.getClass(),
                new CGLIBDynamicProxy(target));

        Landlord proxy2=(Landlord) Enhancer.create(
                target1.getClass(),
                new CGLIBDynamicProxy(target1));

        //使用代理对象
        proxy1.saleHouse();
        proxy1.rentHouse();

        proxy2.saleHouse();
        proxy2.rentHouse();
    }
}

得到的结果如下:

成功进行了代理操作

相关推荐
晚安日记wanna11 分钟前
Redis 持久化RDB 和 AOF 到底该怎么选
redis·面试·架构
小蒜学长19 分钟前
基于RFID技术的仓储管理系统设计(代码+数据库+LW)
java·数据库·spring boot·后端·rfid技术·仓储管理
梦影_27 分钟前
Langchain简单快速上手教程(五)——聊天模型之流式传输
java·数据库·人工智能·python·langchain
数据狐(Datafox)42 分钟前
1688商品列表API接口解析(附 JSON 样例)
java·开发语言·数据库·爬虫·json
xcl09251 小时前
健身场馆无人自动化系统:从架构设计到落地实践
java·spring boot
EatFan1 小时前
一个二维码背后的系统设计:批次生成、绑定、扫码与数据统计怎么做?
java·后端·微信小程序·二维码·qrcode
白远山1 小时前
自助健身小程序源码:架构拆解、核心链路与本地部署实战
java·架构·uni-app·需求分析
Lyyaoo.1 小时前
【动态规划】【待更新】
java·数据结构·算法
hqyjzsb1 小时前
规划工商管理大学成长:搭建四层能力体系,重视高阶的 AI 能力建设
开发语言·人工智能·python·microsoft·职场和发展·数据挖掘·业界资讯
我不会起名字3221 小时前
一天一道算法题(35):电话号码的字母组合
java·数据结构·后端·python·leetcode·go·回溯