继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!
火车站卖票案例
代码:
//抽象主题
public interface SellTickets { void sellTickets();
}
//真实主题
public class TrainStation implements SellTickets{ @Override public void sellTickets() { System.out.println("火车站卖票"); }
}
//代理类
public class ProxyPoint implements SellTickets{ private TrainStation station = new TrainStation(); @Override public void sellTickets() { System.out.println("代理商收取服务费"); station.sellTickets(); }
}
public class ProxyFactory{
// 声明目标对象 private TrainStation station = new TrainStation(); public SellTickets getProxyObjects() { /*ClassLoader loader, 类加载器,用于加载代理类,可以通过目标对象获取类加载器 Class>[] interfaces,代理类实现的接口的字节码对象 InvocationHandler h 代理对象调用的调用处理程序 * */ SellTickets proxyInstance = (SellTickets) Proxy.newProxyInstance( station.getClass().getClassLoader(), station.getClass().getInterfaces(), new InvocationHandler() { /*Object 代理对象,和proxyInstance是同一个对象,在invoke中基本不用 Method 代理对象调用方法,对接口中方法进行封装的对象,这里是sellTickets Object[] 调用方法参数 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理商收取服务费(JDK动态代理)");
// 执行目标对象的方法 Object invoke = method.invoke(station, args); return invoke; } } ); return proxyInstance; }
}//测试public static void main(String[] args) {
// 获取代理对象
// 创建代理工厂对象 ProxyFactory proxyFactory = new ProxyFactory();
// 使用代理工厂创建代理对象 SellTickets proxyObjects = proxyFactory.getProxyObjects();
// 调用买票方法 proxyObjects.sellTickets(); }
java -jar arthas-boot.jar
,如图com.sun.proxy.$Proxy0
,如图public final class $Proxy0 extends Proxy implements SellTickets {
private static Method m3;
public $Proxy0(InvocationHandler invocationHandler) { super(invocationHandler);
}
static { m3 = Class.forName("com.demo.patternDesign.ProxyModel.DynamicJDKProxy.SellTickets").getMethod("sellTickets", new Class[0]);
}
// 代理类调用真实对象方法
public final void sellTickets() {
this.h.invoke(this, m3, null);
}
}
```
和之前一样的案例
cglib cglib 3.3.0
// 代理工厂
public class ProxyFactory implements MethodInterceptor {
// 创建真实对象 private TrainStation trainStation = new TrainStation(); public TrainStation getProxyObject(){
// 创建Enhance对象,类似于JDK代理中的Proxy类 Enhancer enhancer = new Enhancer();
// 设置父类的字节码对象 enhancer.setSuperclass(TrainStation.class);
设置回调函数 enhancer.setCallback(this);
// 创建代理对象 TrainStation proxyObject = (TrainStation) enhancer.create(); return proxyObject; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("代理商收取服务费(cglib代理)"); Object invoke = method.invoke(trainStation,objects); return invoke; }
}
// 测试代码public static void main(String[] args) {
// 创建代理工厂对象 ProxyFactory proxyFactory = new ProxyFactory();
// 获取代理对象 TrainStation proxyObject = proxyFactory.getProxyObject(); proxyObject.sellTickets();}
增加系统复杂度
本地服务通过网络请求远程服务:可将网络通信部分隐藏,只保留本地服务一个接口,使其通过此接口访问远程服务提供功能,而不必过多关心通信细节。
将浏览器配置成代理模式,防火墙将请求转发给互联网,当互联网响应时,代理服务器将信息再转发给浏览器
控制一个对象访问,若需要,可以给不同对象以不同访问权限
下一篇:java spring下载步骤