Spring支持5种类型的增强:
1).前置增强
org.springframework.aop.BeforeAdvice代表前置增强.spring目前只支持方法级的增强, 所以MethodBeforeAdvice是目前可用可用的前置增强, 表示在目标方法执行前执行增强.
2).后置增强
org.springframework.aop.AfterReturningAdvice代表后置增强, 表示在目标方法返回后实施增强逻辑
3).环绕增强
org.aopalliance.intercept.MethodInterceptor表示环绕增强, 在方法执行前后执行增强.
4).异常抛出增强
org.springframework.aop.ThrowsAdvice表示异常抛出增强, 在方法抛出异常后实施增强.
5).引介增强
org.springframework.aop.IntroductionInterceptor表示引介增强, 可以在目标类中增加一些新的方法和属性.
这些增强接口都有一些方法, 通过实现这些接口方法, 这方法中定义横切逻辑,就可以将他们织入到目标类方法的相应连接点的位置.
1.前置增强
下面通过规范服务员的礼貌用于来演示前置增强.
服务员:
package com.bao.bao.aop; /** * Created by xinfengyao on 16-7-4. */ public interface Waiter { void greetTo(String name); void serveTo(String name); }
一个训练不足的服务员:
package com.bao.bao.aop; /** * Created by xinfengyao on 16-7-4. */ public class NaiveWaiter implements Waiter { @Override public void greetTo(String name) { System.out.println("greet to " + name + "..."); } @Override public void serveTo(String name) { System.out.println("serving " + name + "..."); } }
NaiveWaiter服务员只是简单地走到客人面前提供服务, 没有任何礼貌用语. 下面通过前置增强, 来规范服务员的服务行为.
增强逻辑:
package com.bao.bao.aop; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /** * Created by xinfengyao on 16-7-4. */ public class GreetingBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object o) throws Throwable { String clientName = (String) args[0]; System.out.println("How are you! Mr." + clientName + "."); } }
BeforeAdvice是前置增强的接口, MethodBeforeAdvice是其子类, MethodBeforeAdvice只定义了一个方法:
public void before(Method method, Object[] args, Object obj) throws Throwable
method为目标类的方法, args为方法的入参, obj为目标类实例.
礼貌用语的前置增强定义好后, 下面我们将强制规范服务生的礼貌用语
package com.bao.bao.aop; import org.springframework.aop.BeforeAdvice; import org.springframework.aop.framework.ProxyFactory;/** * Created by xinfengyao on 16-7-4. */ public class TestBeforeAdvice { public static void main(String[] args) throws Exception { Waiter target = new NaiveWaiter(); BeforeAdvice advice = new GreetingBeforeAdvice(); ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTarget(target); proxyFactory.addAdvice(advice); Waiter proxy = (Waiter) proxyFactory.getProxy(); proxy.greetTo("John"); proxy.serveTo("Tom"); } }
运行结果:
How are you! Mr.John. greet to John... How are you! Mr.Tom. serving Tom...
正如我们所看到的一样, 礼貌用语得到的实施.
ProxyFactory就是通过JDK代理和CGLIB代理, 将增强织入到目标类中.
spring定义了org.springframework.aop.framework.AopProxy接口,并提供了两个final类型实现类
ProxyFactory的setInterfaces(Class[] Interfaces)指定只对接口进行代理,ProxyFactory就是用JdkDynamicAopProxy;如果是针对类型的代理,则使用Cglib2AopProxy
另外ProxyFactory的setOptimize(true)方法,让ProxyFactory启动优化代理方式,这样,针对接口的代理也会使用Cglib2AopProxy 。
......