Spring笔记(三)AOP前篇之动态代理
AOP思想是将程序中的业务代码与服务代码进行分离,在运行时进行结合。比较强调程序的层次结构,是一种面向切面的编程。而在AOP实现的底层主要用到了动态代理,而动态代理又分为JDK动态代理和CGLIB动态代理,两者的区别是JDK动态代理的实现中业务类必须必须定义接口,而CGLIB没有这个约束,可以说CGLIB更强大;
JDK动态代理实现示例:
| 1 | // 业务接口定义 |
| 2 | public interface IUnit { |
| 3 | void execute(String msg); |
| 4 | } |
| 5 | |
| 6 | // 业务实现类 |
| 7 | public class Unit implements IUnit{ |
| 8 | @Override |
| 9 | public void execute(String msg) { |
| 10 | System.out.println("execute:"+msg); |
| 11 | } |
| 12 | } |
| 13 | |
| 14 | // 服务实现类 |
| 15 | public class Reference { |
| 16 | void showMessage(String msg){ |
| 17 | System.out.println("Reference:"+msg); |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | // 动态代理实现类 |
| 22 | public class UnitProxy { |
| 23 | // 业务代码对象 |
| 24 | IUnit iunit = new Unit(); |
| 25 | // 服务代码对象 |
| 26 | Reference reference = new Reference(); |
| 27 | // 获取代理对象 |
| 28 | IUnit getProxy() { |
| 29 | /** |
| 30 | * 函数名:newProxyInstance |
| 31 | * 参数一:代理类类加载器 |
| 32 | * 参数二:服务类接口 |
| 33 | * 参数三:代理对象调用处理程序实现接口 |
| 34 | */ |
| 35 | return (IUnit)Proxy.newProxyInstance(UnitProxy.class.getClassLoader(), iunit |
| 36 | .getClass().getInterfaces(), new InvocationHandler() { |
| 37 | /** |
| 38 | * 函数名:invoke |
| 39 | * 参数一:代理对象 |
| 40 | * 参数二:调用的服务类方法对象 |
| 41 | * 参数三:服务类方法参数 |
| 42 | */ |
| 43 | @Override |
| 44 | public Object invoke(Object proxy, Method method, Object[] args) |
| 45 | throws Throwable { |
| 46 | Object retObject = null; |
| 47 | reference.showMessage("getProxy before"); |
| 48 | retObject = method.invoke(iunit, args); |
| 49 | reference.showMessage("getProxy after"); |
| 50 | return retObject; |
| 51 | } |
| 52 | }); |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | public class TestApplication { |
| 57 | public static void main(String[] args){ |
| 58 | UnitProxy proxy = new UnitProxy(); |
| 59 | IUnit iunit = proxy.getProxy(); |
| 60 | iunit.execute("TestApplication execute"); |
| 61 | } |
| 62 | } |
这段代码中的关键函数为 Proxy.newProxyInstance ,我对它的理解为:通过代理类的类加载器和业务类接口,在代理对象处理程序实现接口中,结合服务对象完成代理对象的构建,代理对象的实现本质是业务类与服务类功能的结合;
在AOP开发中通常会提到目标对象、服务对象、代理对象、连接点、切入点、切面、增强,最后结合以上代码说明下:
UnitProxy 类中的iunit 为目标对象,reference 为服务对象,getProxy方法返回的是代理对象。IUnit 接口中定义的接口全部为连接点,切入点是连接点的子集,也就是复合一定条件的连接点。切面就是服务类Reference。增强是服务类Reference中的方法showMessage;

浙公网安备 33010602011771号