一、认识代理模式 1、代理是什么?
代理也称“委托”,分为静态代理和动态代理,代理模式也是常用的设计模式之一,具有方法增强、高扩展性的设计优势。其设计就是限制直接访问真实对象,而是访问该对象的代理类。这样的话,我们就保护了内部对象,如果有一天内部对象因为某个原因换了个名或者换了个方法字段等等,那对访问者来说一点不影响,因为他拿到的只是代理类而已,从而使该访问对象具有高扩展性。然而,代理类可以实现拦截方法,修改原方法的参数和返回值,满足了代理自身需求和目的,也就是是代理的方法增强性。
2、静态代理:
创建一个Image接口显示方法
public interface Image { void display(); }创建一个RealImage类实现Image接口
public class RealImage implements Image { private String fileName; public RealImage(String fileName){ this.fileName = fileName; loadFromDisk(fileName); } @Override public void display() { System.out.println("Displaying " + fileName); } private void loadFromDisk(String fileName){ System.out.println("Loading " + fileName); } }创建代理类Proxy实现Image接口
public class ProxyImage implements Image{ //被代理的类作为成员变量 private RealImage realImage; private String fileName; public ProxyImage(String fileName){ this.fileName = fileName; } @Override public void display() { //创建被代理对象实例 if(realImage == null){ realImage = new RealImage(fileName); } realImage.display(); } }当被请求时,使用 ProxyImage 来获取 RealImage 类的对象。
public class ProxyPatternDemo { public static void main(String[] args) { Image image = new ProxyImage("test_10mb.jpg"); // 图像将从磁盘加载 image.display(); System.out.println(""); // 图像不需要从磁盘加载 image.display(); } }3、动态代理:
是JDK提供的代理方式且只支持接口,在JVM虚拟机运行时动态生成一系列代理,主要通过Java提供的InvocationHanler类实现。当静态代理类特别多的时候,我们就可以不用手写每一个静态代理类了,也不需要制定代理谁,在运行的时候指定一个代理类就行了,变得更灵活了。实现步骤:
写一个类实现InvocationHanlder接口;重写接口的invoke方法;调用Proxy.newProxyInstance()返回一个代理对象;案例: Subject.java
public interface Subject { String operation(); }创建一个RealSubject类实现Subject接口
public class RealSubject implements Subject{ @Override public String operation() { return "operation by subject"; } }创建代理类ProxySubject.java实现InvocationHandler接口
public class ProxySubject implements InvocationHandler{ protected Subject subject; public ProxySubject(Subject subject) { this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //do something before return method.invoke(subject, args); } }newProxyInstance.java
public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces,InvocationHandler h) throws IllegalArgumentException { // 检查 h 不为空,否则抛异常 if (h == null) { throw new NullPointerException(); } // 获得与指定类装载器和一组接口相关的代理类类型对象 Class cl = getProxyClass(loader, interfaces); // 通过反射获取构造函数对象并生成代理类实例 try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) {... }调用代码:
Subject subject = new RealSubject(); //被代理对象 ProxySubject proxy = new ProxySubject(subject);//代理类 Subject sub = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), proxy); sub.operation();———————————————— 版权声明:本文为博主「艾阳丶」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/csdn_aiyang/article/details/79085039