代理模式的一个典型应用:AOP(面向切面编程)
代理
a类本来需要调用c类(目标类)的方法完成某个功能, 但是c不让a调用。
a —>不能直接调用 c的方法。
在a 和 c 直接创建一个 b 代理,c让b访问。 c,b实现相同的功能(接口)。
a —>访问b—>访问c
作用:
- 功能增强: 在原有的功能上,增加了额外的功能。 新增加的功能,叫做功能增强
- 控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。
静态代理
代理类需要手工实现。即自己创建一个java类,表示代理类。所要代理的目标类是确定的。
- 缺点:当目标类和代理类很多时候,
- 当目标类增加, 代理类可能也需要成倍的增加。 代理类数量过多。
- 当接口中功能增加或修改,会影响众多的实现类,厂家类,代理类都需要修改。影响较大。
动态代理
在程序执行过程中,使用jdk的反射机制,创建代理类对象, 并动态的指定要代理目标类。
即使目标类很多,代理类数量可以很少;当修改了接口中的方法时,不影响代理类。
动态代理是一种创建java对象的能力,不用创建代理类,就能创建代理类对象。
两种实现方式:jdk动态代理;cglib动态代理
jdk动态代理
- 使用java反射包中的类和接口实现动态代理的功能。
- 反射包 java.lang.reflect , 里面有三个类 : InvocationHandler , Method, Proxy.
- 要求目标类实现接口
1 | // 不使用反射调用方法 |
- InvocationHandler接口,只有一个方法invoke(),代理对象要完成的功能。(目标方法/功能增强)
- Method类:表示目标类中的方法。通过Method可以执行某个目标类的方法,method.invoke(目标对象,方法的参数)
- Proxy类:创建代理对象。之前创建对象是 new ,现在使用Proxy类的静态方法 newProxyInstance() 。
1 | //实现InvocationHandler接口,完成代理类要做的功能(1.调用目标方法,2.功能增强) |
1 | //创建代理对象,使用Proxy |
cglib动态代理
- cglib是第三方的工具库, 创建代理对象。
- 原理是继承, cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改。要求目标类不能是final的, 方法也不能是final的。
- cglib的要求目标类比较宽松, 只要能继承即可。