设计模式-代理模式
模式定义
给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用
为什么使用代理
在不改变目标对象方法的情况下对方法进行增强
代理模式实例
静态代理
先创建一个用户接口(UserInterface),声明一个方法
public interface UserInterface {
void service(String s);
}
创建实现类(UserImpl)
public class UserImpl implements UserInterface {
@Override
public void service(String s) {
System.out.println("我是" + s);
}
}
创建代理对象类(UserProxy),通过代理类创建实现类实例并访问其方法
public class UserProxy implements UserInterface {
private UserInterface user;
public UserProxy(UserImpl user) {
this.user = user;
}
@Override
public void service(String s) {
System.out.println("检查身份");
user.service(s);
System.out.println("请进门");
}
}
客户端调用
public class ProxyTest {
public static void main(String[] args) {
UserImpl user = new UserImpl();
UserProxy proxy = new UserProxy(user);
proxy.service("wupx");
}
}
输出结果
检查身份
我是wupx
请进门
动态代理
先创建一个User接口
public interface User {
void code();
void sleep();
}
创建User的实现类(UserImpl)
public class UserImpl implements User {
@Override
public void code() {
System.out.println("开始敲代码");
}
@Override
public void sleep() {
System.out.println("开始睡觉");
}
}
再创建一个代理类(UserImpProxy)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserImpProxy implements InvocationHandler {
private User user;
public UserImpProxy(User user) {
this.user = user;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
Object result;
if ("code".equals(methodName)) {
System.out.println("讨论需求");
result = method.invoke(user, args);
System.out.println("提测");
} else if ("sleep".equals(methodName)) {
System.out.println("洗澡");
result = method.invoke(user, args);
} else {
result = method.invoke(user, args);
}
return result;
}
}
去测试动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class TestProxy {
public static void main(String[] args) {
UserImpl user = new UserImpl();
InvocationHandler userProxyHandler = new UserImpProxy(user);
User userProxy = (User) Proxy.newProxyInstance(user.getClass().getClassLoader(),
user.getClass().getInterfaces(), userProxyHandler);
userProxy.code();
userProxy.sleep();
}
}
运行结果
讨论需求
开始敲代码
提测
洗澡
开始睡觉
总结
使用Java动态代理的两个重要步骤
- 通过实现 InvocationHandler 接口创建自己的调用处理器;
- 通过为Proxy类的newProxyInstance方法指定代理类的ClassLoader 对象和代理要实现的interface以及调用处理器InvocationHandler对象来创建动态代理类的对象;