本文共 4205 字,大约阅读时间需要 14 分钟。
不知不觉今天已经7月底了,时间过得真快,这个月真热,这篇文章主要来介绍代理模式。
代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问
如下图所示
这里是结合springAop,仿造它的实现
public interface Subject { void request();}// 请求的真实目标对象public class RealSubject implements Subject { @Override public void request() { System.out.println("real subject execute request"); }}// 代理对象public class Proxy implements Subject { private RealSubject realSubject; public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void request() { System.out.println("before"); try { realSubject.request(); } catch (Exception e) { System.out.println("ex:" + e); throw e; } finally { System.out.println("after"); } }}
客户端调用代码
public class Client { public static void main(String[] args) throws Exception { Subject subject = new Proxy(new RealSubject()); subject.request(); }}
运行结果
beforereal subject execute requestafter
静态代理有一个很明显的缺点:代理的方法越多,重复代码越多。
就不符合DRY原则。于是 就产生了动态代理JDK 为我们提供了一种动态代理的实现,通过实现 InvocationHandler 接口来实现动态代理。
代理类代码
public class JdkProxySubject implements InvocationHandler { private RealSubject realSubject; public JdkProxySubject(RealSubject realSubject) { this.realSubject = realSubject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before"); Object result = null; try { result = method.invoke(realSubject, args); } catch (Exception e) { System.out.println("ex" + e); throw e; } finally { System.out.println("after"); } return result; }}
客户端类代码
public class Client { public static void main(String[] args) throws Exception { Subject subject = (Subject) Proxy.newProxyInstance(Client.class .getClassLoader(), new Class[]{Subject.class}, new JdkProxySubject(new RealSubject())); subject.request(); }}
运行结果
beforereal subject execute requestafter
上面讲了动态代理是解决代码重复的问题。我们来验证下
首先,在Subject 接口中增加一个hello方法
public interface Subject { void request(); void hello();}public class RealSubject implements Subject { @Override public void request() { System.out.println("real subject execute request"); } @Override public void hello() { System.out.println("real subject execute hello"); }}
静态代理类 如果想要代理hello 这个方法。就要在代理类中实现这个方法
public class Proxy implements Subject { private RealSubject realSubject; public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void hello() { ... }}
我们看动态代理类,无需改变,直接运行测试类
public class Client { public static void main(String[] args) throws Exception { Subject subject = (Subject) Proxy.newProxyInstance(Client.class .getClassLoader(), new Class[]{Subject.class}, new JdkProxySubject(new RealSubject())); subject.hello(); }}
运行结果
beforereal subject execute helloafter
代理类
public class DemoMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before in cglib"); Object result = null; try { result = proxy.invokeSuper(object,args); }catch (Exception e){ System.out.println("get ex :" + e.getMessage()); throw e; }finally { System.out.println("after in cglib"); } return result; }}
调用
public class Client { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealSubject.class); enhancer.setCallback(new DemoMethodInterceptor()); Subject subject = (Subject) enhancer.create(); subject.request(); }}
运行结果
before in cglibreal subject execute requestafter in cglib
代理模式暂时先分析到这,玩的开心!
学习不是要么0分,要么100分的。80分是收获;60分是收获;20分也是收获。有收获最重要。但是因为着眼于自己的不完美,最终放弃了,那就是彻底的0分了。转载地址:http://hkmpa.baihongyu.com/