在《静态代理和动态代理》中提到了面向方面编程,主要就是基于动态代理。单独抽象出非业务的功能,服务于某些业务方法。Spring提供了四种很实用的Advice,分别为:Before Advice, After Returning Advice, Around Advice, After throwing Advice。都是方法级别的,就是在某个方法执行前后插入一些非业务的操作,如打日志或者判断权限等。
对于这四种advice的实现,spring都提供了三种方法,分别为基于接口、基于xml和基于annotation(注释)。Before Advice会在目标对象的方法执行之前被调用;After Advice会在目标方法执行之后被调用;Around Advice则可以在目标方法执行前后同时加上相关服务;Throw Advice是在异常发生后执行某些操作。
1.基于接口的Advice
这个就需要自定义的Aspect实现Spring接口。
BeforeAdvice需要实现org.springframework.aop.MethodBeforeAdvice接口:
After Advice实现org.springframework.aop.AfterReturningAdvice接口:
Around Advice需要实现org.aopalliance.intercept.MethodInterceptor接口:
类前面的注释说明了该方法的使用,就是要在invoke()方法中调用MethodInvocation.proceed(),将执行传给下一个Interceptor,最终执行目标方法。在proceed()方法前后加操作,到达Aroud advice的作用。
在Aspect定义好后,就需要在bean定义文件中进行配置,通过org.springframework.aop.framework.ProxyFactoryBean的配置,指出接口、目标类和Aspect。如下:
补充下,其中的目标类、解释器(Aspect)都要在Bean定义文件中先进行定义,然后才可以引用的。我们使用时,代码如下:
在Bean定义文件中配置的Aspect就会在合适的joinPoint应用到目标方法上。补:IHello接口中有hello()方法,HelloSpeaker类实现了IHello接口。
以免糊涂,给个实例如下,功能是在hello()方法前后加入日志记录。
配置:
IHello helloProxy=(IHello)context.getBean("helloProxy");helloProxy.hello("前后加日志");就会出现如下结果: