推荐先看JDK 动态代理(Spring AOP 的原理)(面试重点)
????????JDK 动态代理有?个最致命的问题是其只能代理实现了接?的类.
????????有些场景下,我们的业务代码是直接实现的,并没有接?定义.为了解决这个问题,我们可以?CGLIB 动态代理机制来解决.
????????CGLIB(Code Generation Library)是?个基于ASM的字节码?成库,它允许我们在运?时对字节码进? 修改和动态?成. CGLIB 通过继承?式实现代理, 很多知名的开源框架都使?到了CGLIB.例如 Spring??中的 AOP 模块中: 如果?标对象实现了接?,则默认采? JDK 动态代理, 否则采?? ?CGLIB 动态代理.
????????和 JDK 动态代理不同, CGLIB(Code Generation Library) 实际是属于?个开源项?,如果你要使?它的话,需要?动添加相关依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
目标类实现的接口 :
//声明房东(目标对象)要执行的相关操作
public interface HouseSubject {
void rentHouse(); //出租房子
void saleHouse(); //卖房子
}
目标类:
public class Landlord implements HouseSubject{
@Override
public void rentHouse() {
System.out.println("房东出租房子");
}
@Override
public void saleHouse() {
System.out.println("房东卖房子");
}
}
// 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;
}
}
//创建代理对象并使用
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();
}
}
? ? ? ? 成功进行了代理操作