0 概述
代理模式(Proxy Pattern)是一种使用的非常高的模式,其定义如下:为其它对象提供一种代理以控制这个对象的访问。
1 实例分析
接口定义
public interface UserService {
String queryUserNameById(long userId);
}
接口实现类
public class UserServiceImpl implements UserService {
public String queryUserNameById(long userId) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "test";
}
}
代理类对象实现 被代理对象服务执行时间记录
public class UserServiceProxy implements UserService {
//被代理对象
private UserService target;
public UserService getTarget() {
return target;
}
public void setTarget(UserService target) {
this.target = target;
}
public String queryUserNameById(long userId) {
Long start = System.currentTimeMillis();
String name = target.queryUserNameById(userId);
Long end = System.currentTimeMillis();
System.out.printf("time:" + (end - start));
return name;
}
}
下图给出代理模式类图关系:
- Subject 抽象主题角色,可以是抽象类或者接口。(实例中UserService)
- RealSubject 具体的主题角色,被代理角色,是具体的业务执行者(实例中UserServiceImpl)
- Proxy 代理主题角色,也叫委托类、代理类。(实例中UserServiceProxy)
2 动态代理
代理对象生成类,采用JDK自带Proxy类生成
public class DynamicProxy<T> {
@SuppressWarnings("unchecked")
public static <T> T newProxyInstance(T subject) {
ClassLoader classLoader = subject.getClass().getClassLoader();
Class<?>[] interfaces = subject.getClass().getInterfaces();
InvocationHandler invocationHandler = new ProxyHandler(subject);
return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
}
}
//代理对象,其中invoke 方法是InvocationHandler接口定义必须实现的,它完成对真实方法的调用。所有的被代理的方法都由InvocationHandler接管实际处理,也就是说Proxy生成的代理对象会调用InvocationHandler的invoke方法。
public class ProxyHandler implements InvocationHandler {
public ProxyHandler(Object target) {
this.target = target;
}
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Long start = System.currentTimeMillis();
//执行被代理方法
Object ob = method.invoke(target,args);
Long end = System.currentTimeMillis();
System.out.printf("time:" + (end - start));
return ob;
}
}
测试类:
public class Test {
public static void main(String[] args) {
UserService service = new UserServiceImpl();
UserService service1 = DynamicProxy.newProxyInstance(service);
service1.queryUserNameById(1);
}
}