Java设计模式之代理模式
文章目录
前言
- 掌握代理模式的应用场景和实现原理
- 了解静态代理和动态代理的区别
- 了解CGLib和JDK Proxy的根本区别
- 手写实现动态代理
一、代理模式
代理模式(Proxy Pattern)是指为其他对象提供一种代理,以控制对这个对象的访问
代理对象在客户端和目标对象之间起到中介作用
根据代理的创建时期,代理模式分为静态代理和动态代理
二、使用场景
- 保护目标对象
- 增强目标对象
三、静态代理
由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。显示声明被代理的对象
1. 抽象主题类
/**
* 抽象主题
*/
public interface ISubject {
void request();
}
2. 真实主题类
/**
* 真实主题
*/
public class RealSubject implements ISubject {
@Override
public void request() {
System.out.println("真实主题方法");
}
}
3. 代理类
/**
* 代理类
*/
public class Proxy implements ISubject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("访问前。。。");
realSubject.request();
System.out.println("访问后。。。");
}
}
4. 客户端
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy(new RealSubject());
proxy.request();
}
}
四、动态代理
在程序运行时,运用反射机制动态创建而成。
1. 抽象主题类
/**
* 抽象主题
*/
public interface ISubject {
void request();
}
2. 真实主题类
/**
* 真实主题
*/
public class RealSubject implements ISubject {
@Override
public void request() {
System.out.println("真实主题方法");
}
}
3. JDK代理工厂
/**
* 代理工厂
*/
public class ProxyFactory implements InvocationHandler {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Proxy getTarget() {
return (Proxy) Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("访问前");
Object invoke = method.invoke(target, args);
System.out.println("访问后");
return invoke;
}
}
4. 客户端
public class Client {
public static void main(String[] args) {
ProxyFactory proxy = new ProxyFactory(new RealSubject());
ISubject target = (ISubject) proxy.getTarget();
target.request();
}
}
五、CGLib代理
1. 真实主题类
/**
* 真实主题
*/
public class RealSubject {
public void request() {
System.out.println("真实主题方法");
}
}
2. CGLib代理工厂
/**
* 代理工厂
*/
public class CGLibFactory implements MethodInterceptor {
public Object getTarget(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("访问前");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("访问后");
return invoke;
}
}
3. 客户端
public class Client {
public static void main(String[] args) {
RealSubject target = (RealSubject) new CGLibFactory().getTarget(RealSubject.class);
target.request();
}
}