Java的代理模式是一种设计模式,它能够在不改变对象自身的情况下,为对象提供一个代理对象,该代理对象可以在访问目标对象时附加一些额外的行为。Java提供了两种代理方式:静态代理和动态代理。这里我们主要介绍JDK动态代理。
JDK动态代理
JDK动态代理是通过Java的反射机制实现的。它可以在运行时为一个或多个接口生成代理类,而不需要手动创建代理类。这一特性使得动态代理在许多场景下都非常方便,尤其是在AOP(面向切面编程)中应用广泛。
1. 创建接口
首先,我们需要定义一个接口。假设我们有一个简单的业务接口 UserService
,提供一个 addUser
方法。
public interface UserService {
void addUser(String user);
}
2. 实现接口
然后,我们实现这个接口,并定义相应的业务逻辑。
public class UserServiceImpl implements UserService {
@Override
public void addUser(String user) {
System.out.println("用户 " + user + " 被添加成功!");
}
}
3. 创建动态代理
接下来,我们创建一个动态代理类,实现 InvocationHandler
接口。InvocationHandler
是一个接口,用于处理对代理实例的方法调用。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyHandler implements InvocationHandler {
private Object target; // 需要代理的真实对象
public DynamicProxyHandler(Object 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;
}
}
4. 创建代理对象
最后,我们可以使用 Proxy
类来创建动态代理对象:
public class Main {
public static void main(String[] args) {
// 创建真实对象
UserService userService = new UserServiceImpl();
// 创建动态代理
DynamicProxyHandler handler = new DynamicProxyHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
handler);
// 使用代理对象
proxy.addUser("张三");
}
}
编译与运行
上面的代码可以编译成 .class
文件。在命令行下,你可以使用以下命令编译所有Java文件:
javac UserService.java UserServiceImpl.java DynamicProxyHandler.java Main.java
然后,运行 Main
类:
java Main
运行结果
运行结果如下:
准备添加用户...
用户 张三 被添加成功!
用户添加完成!
总结
通过JDK动态代理,我们能够在不修改目标类的情况下,动态地为其增加一些额外的功能,这在很多场景下非常有用,比如权限控制、事务管理、日志记录等。在实际项目中,利用Spring框架的AOP特性,可以更加方便地使用代理模式,使得代码更加简洁和易于维护。