代理模式分为静态代理和动态代理 .
静态代理:
- 接口
public interface Subject {
public void request();
}
- 代理类
public class ProxySubject implements Subject {
private Subject subject;
public ProxySubject(Subject subject) {
this.subject = subject;
}
@Override
public void request() {
System.out.println("------start------");
this.subject.request();
System.out.println("------end------");
}
}
- 实际业务类
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("---实际业务操作---");
}
}
- 客户端
public class Client {
public static void main(String[] args) {
// 创建出业务对象
Subject realSubject = new RealSubject();
// 将业务对象设置给代理对象
Subject proxySubject = new ProxySubject(realSubject);
// 执行业务对象
proxySubject.request();
}
}
动态代理:
动态代理中,代理类并不是在Java代码中实现,而是在运行时期生成,相比静态代理,动态代理可以很方便的对委托类的方法进行统一处理,如添加方法调用次数、添加日志功能等等,动态代理分为jdk动态代理和cglib动态代理,下面通过一个例子看看如何实现jdk动态代理
- 接口
public interface UserService {
public void add();
}
- 实现类
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("---这是实际业务操作---");
}
}
- Invocation
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("----start----");
Object result = method.invoke(target, args);
System.out.println("----end----");
return result;
}
// 生成代理对象
public Object getProxy() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
// 第一个参数:classLoader, 第二个参数业务对象接口数组 第三个是MyInvocation对象
return Proxy.newProxyInstance(classLoader, interfaces, this);
}
}
- 客户端
public class Client {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
MyInvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService proxyUserService = (UserService) invocationHandler.getProxy();
proxyUserService.add();
}
}
代理对象生成过程由Proxy类的newProxyInstance方法实现, 分为三个步骤 :
1.ProxyGenerator.generateProxyClass方法负责生成代理类的字节码,生成逻辑比较复杂
2.native方法Proxy.defineClass0负责字节码加载的实现,并返回对应的Class对象
3.利用clazz.newInstance反射机制生成代理类的对象;