引言
在Java编程中,动态代理是一种非常有用的技术。它允许我们在运行时生成代理类,以便在代理类中可以添加额外的逻辑。Java中有两种主要的动态代理技术,一种是JDK动态代理,另一种是CGLIB。
本篇博客将详细介绍Java中动态代理的用法,并讲解CGLIB这种更加强大的代理技术。
JDK动态代理
JDK动态代理是Java提供的一种基于接口的代理技术。它基于Java反射机制,通过实现java.lang.reflect.InvocationHandler
接口来实现代理类。
步骤
使用JDK动态代理主要有以下几个步骤:
- 创建一个实现
InvocationHandler
接口的类,通常称为代理处理器。 - 在代理处理器中实现
invoke
方法,在该方法中添加额外的逻辑。 - 使用
Proxy
类的静态方法newProxyInstance
创建代理类的实例。
示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public interface Foo {
void bar();
}
public class FooImpl implements Foo {
@Override
public void bar() {
System.out.println("执行原始对象的方法");
}
}
public class FooHandler implements InvocationHandler {
private final Foo target;
public FooHandler(Foo target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("在调用原始方法之前执行的逻辑");
Object result = method.invoke(target, args);
System.out.println("在调用原始方法之后执行的逻辑");
return result;
}
}
public class Main {
public static void main(String[] args) {
Foo target = new FooImpl();
Foo proxy = (Foo) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new FooHandler(target));
proxy.bar();
}
}
输出结果:
在调用原始方法之前执行的逻辑
执行原始对象的方法
在调用原始方法之后执行的逻辑
CGLIB代理
CGLIB(Code Generation Library)是一个基于字节码生成技术的代理库。与JDK动态代理不同,它不依赖于接口,可以代理任何类(甚至是final类)。
步骤
使用CGLIB代理的步骤如下:
- 引入CGLIB库,可以在Maven项目的pom.xml中添加以下依赖:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
- 创建一个类来作为代理目标,不需要实现接口。
- 创建一个类来作为代理处理器,实现
MethodInterceptor
接口。 - 在代理处理器中实现
intercept
方法,在该方法中添加额外的逻辑。 - 使用CGLIB的
Enhancer
类来创建代理类的实例。
示例
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.Enhancer;
public class Foo {
public void bar() {
System.out.println("执行原始对象的方法");
}
}
public class FooHandler implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("在调用原始方法之前执行的逻辑");
Object result = proxy.invokeSuper(obj, args);
System.out.println("在调用原始方法之后执行的逻辑");
return result;
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Foo.class);
enhancer.setCallback(new FooHandler());
Foo proxy = (Foo) enhancer.create();
proxy.bar();
}
}
输出结果:
在调用原始方法之前执行的逻辑
执行原始对象的方法
在调用原始方法之后执行的逻辑
总结
动态代理是一个非常实用的Java编程技术,它可以在运行时为目标对象添加一些额外的逻辑。在Java中,我们使用JDK动态代理来代理接口,使用CGLIB代理来代理类。通过掌握动态代理的用法,我们可以更好地设计和编写可扩展且可维护的代码。
本文来自极简博客,作者:时光旅人,转载请注明原文链接:Java中的动态代理与CGLIB用法