深入理解Java中的代理模式及其实现
1. 代理模式概述
代理模式是一种结构型设计模式,其目的是通过代理对象控制对其他对象的访问。代理模式常用于实现日志记录、性能监控、权限控制等功能,同时它也能够实现延迟加载、按需加载等优化。
2. 静态代理
静态代理是在编译时确定代理类的实现,在Java中通过接口实现代理较为常见。下面是一个简单的示例,展示了如何通过静态代理实现日志记录功能。
2.1 创建接口
package cn.juwatech.proxy;
public interface UserService {
void save(String user);
}
2.2 实现目标对象
package cn.juwatech.proxy;
public class UserServiceImpl implements UserService {
@Override
public void save(String user) {
System.out.println("Saving user: " + user);
}
}
2.3 创建代理类
package cn.juwatech.proxy;
public class UserServiceProxy implements UserService {
private UserService target;
public UserServiceProxy(UserService target) {
this.target = target;
}
@Override
public void save(String user) {
System.out.println("Before saving user");
target.save(user);
System.out.println("After saving user");
}
}
2.4 测试静态代理
package cn.juwatech.proxy;
public class ProxyPatternDemo {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = new UserServiceProxy(target);
proxy.save("Alice");
}
}
3. 动态代理
动态代理是在运行时生成代理类,无需编写代理类的实现。Java中的动态代理主要依赖于java.lang.reflect.Proxy
和java.lang.reflect.InvocationHandler
接口。
3.1 创建InvocationHandler
package cn.juwatech.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class UserServiceInvocationHandler implements InvocationHandler {
private Object target;
public UserServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before invoking method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After invoking method: " + method.getName());
return result;
}
}
3.2 创建动态代理
package cn.juwatech.proxy.dynamic;
import cn.juwatech.proxy.UserService;
import cn.juwatech.proxy.UserServiceImpl;
import java.lang.reflect.Proxy;
public class DynamicProxyPatternDemo {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceInvocationHandler handler = new UserServiceInvocationHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
handler);
proxy.save("Bob");
}
}
4. 总结
通过本文,你深入理解了Java中的代理模式及其两种实现方式:静态代理和动态代理。静态代理适用于编译时已知代理类的情况,而动态代理则能够在运行时生成代理类,提供更大的灵活性和可扩展性。