JDK代理与Cglib代理

本文详细介绍了Java动态代理的两种实现方式——JDK代理和CGLib代理,通过实例展示了它们的原理、使用场景和关键区别,帮助读者理解基于接口的JDK代理与基于父类的CGLib代理的异同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP的动态代理技术

JDK代理

接口Target:

public interface Target {

void targetMethod();

}

接口实现类TargetImpl:

public class TargetImpl implements Target {

@Override

public void targetMethod() {

System.out.println("我是目标方法...");

}

}

增强的切面Aspect:

public class Aspect {

public void PreEnhance(){

System.out.println("我是前置增强...");

}

public void PostEnhance(){

System.out.println("我是后置增强...");

}

}

JDKProxy获取代理类:

public class JDKProxy implements InvocationHandler {

//定义切面

Aspect aspect=new Aspect();

//定义一个目标类的实现接口

private Target target;

public Object createJDKProxy(Target target){

//target进行绑定

this.target=target;

//获取target实现类的类加载器

ClassLoader classLoader = target.getClass().getClassLoader();

//获取target实现类的接口

Class<?>[] interfaces = target.getClass().getInterfaces();

//创建jdk代理,this代表当前的invocationHandler对象

Target proxyTarget = (Target) Proxy.newProxyInstance(classLoader, interfaces, this);

return proxyTarget;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//调用aspect前置增强

aspect.PreEnhance();

//待增强的方法,target为目标类的实现接口

Object invoke = method.invoke(target, args);

//调用aspect后置增强

aspect.PostEnhance();

return invoke;

}

}

创建JDKTest测试类:

public class JDKTest {

public static void main(String[] args) {

JDKProxy jdkProxy = new JDKProxy();

Target target=new TargetImpl();

Target targetProxy = (Target) jdkProxy.createJDKProxy(target);

targetProxy.targetMethod();

}

}

Cglib动态代理

导入Cglib依赖

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>5.3.22</version>

</dependency>

增强的切面Advice

public class Advice {

public void before(){

System.out.println("我是一个前置增强...");

}

public void after(){

System.out.println("我是一个后置增强");

}

}

需要增强的类

public class TargetCglib {

public void save(){

System.out.println("我是cglib切面...");

}

}

CglibProxy代理创建类

public class CglibProxy implements MethodInterceptor {

//实例化Advice

static Advice advice=new Advice();

//定义需要增强的类

TargetCglib targetCglib;

public Object createCglibProxy(TargetCglib targetCglib){

//传入的targetCglib与类中的进行绑定

this.targetCglib=targetCglib;

//创建增强器

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(TargetCglib.class);

enhancer.setCallback(this);

//enhancer调用create创建cglib目标代理对象并返回

return enhancer.create();

}

@Override

public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

//前置增强

advice.PreEnhance();

//待增强的目标

Object invoke = method.invoke(targetCglib, objects);

//后置增强

advice.PostEnhance();

return invoke;

}

}

测试Cglib代理类

public class CglibTest {

public static void main(String[] args) {

CglibProxy cglibProxy = new CglibProxy();

TargetCglib targetCglib = new TargetCglib();

TargetCglib cglibTarget = (TargetCglib) cglibProxy.createCglibProxy(targetCglib);

cglibTarget.cglibMethod();

}

}

总结与对比

重要区别:jdk代理必须含有接口,cglib可以不用有接口,也可以有

jdk代理:基于接口的动态代理技术,jdk自带,反射机制

cglib代理:基于父类的动态代理技术,第三方jar包,fastClass机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值