代理模式
代理模式从字面理解可以和网络中的代理类比,之前的一篇博文中介绍了ngrok反向代理和nginx负载均衡。这整个链路都存在三个主体,客户端对象,代理对象,被代理对象。实际上java编程中代理模式也可以从这个链路过程去考虑。
Java静态代理
Java静态代理的代码实现
1.创建一个明星类接口定义行为:
1 | public interface IMovieStar { |
2.实现这个明星类接口(被代理对象):
1 | public class Star implements IMovieStar { |
3.静态代理类(实现明星类接口,并定义对象):
1 | public class StaticProxyHandler implements IMovieStar { |
4.客户端调用代理对象:
1 | public class Main { |
5.输出结果:
1 | before method |
总结
静态代理实际上是对代理对象的一个组合封装,通过代理对象去增强被代理对象的方法逻辑,在方法执行前增加了代理对象的逻辑,实现了代码的复用和解耦合。缺点是如果接口行为发生改变,如增加了接口,那么代理类和被代理类都需要改变(因为都实现了这个接口),同时如果需要对代理类的每个方法都添加统一的逻辑。如打日志通用的业务逻辑,通过静态代理的方式需要手动增加大量代码,不利于扩展。
Java动态代理
Java动态代理的代码实现
1.动态代理类(实现InvocationHandler接口):
1 | public class ProxyHandler implements InvocationHandler { |
2.客户端调用代理对象:
1 | public class Main { |
3.输出结果:
1 | 100000?价格不达标不演 |
总结
这里的动态代理更准确来说是JDK动态代理,它通过实现InvocationHandler接口的ProxyHandler类以发射的方式动态生成一个代理类(对应于我们上面的StaticProxyHandler)。代理类在调用每个方法时实际上执行的都是ProxyHandler类中的invoke方法,这样我们可以理解到这个代理类实际上是在生成实现类之后在每个方法中进行了反射调用。
Java静态代理与动态代理对比
Java静态代理是静态的,需要手动维护代理类,当接口变动时需要人为感知,同时修改被代理类和代理类,同时需要为每个接口的实现方法去手动添加一套逻辑。动态代理是动态的,接口变动时因为通过反射机制能够追溯到接口的变化情况去动态生成代理类,那么只需要手动修改被代理类即可,同时它会在每个实现方法中去自动添加一套逻辑。
总结
其实一开始想了解Spring AOP,最后发现AOP的面向切面编程也是基于JDK动态代理和CGLIB动态代理实现。之后会重点介绍这两种动态代理的区别已经在Spring AOP中的运用。
在此输入正文