ProxyFactoryBean是SpringAOP实现的核心,先经过代码使用ProxyFactoryBean完成一次AOP调用java
public class App { public static void main(String[] args) { //1.建立ProxyFactoryBean,用以建立指定对象的Proxy对象 ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); proxyFactoryBean.setInterfaces(TicketService.class); proxyFactoryBean.setTarget(new RailwayStation()); proxyFactoryBean.setProxyTargetClass(true); //2.添加Advice拦截器 proxyFactoryBean.addAdvice(new TicketServiceAfterReturningAdvice()); proxyFactoryBean.addAdvice(new TicketServiceAroundAdvice()); proxyFactoryBean.addAdvice(new TicketServiceBeforeAdvice()); proxyFactoryBean.addAdvice(new TicketServiceThrowsAdvice()); //3.获取代理对象 TicketService ticketService = (TicketService)proxyFactoryBean.getObject(); ticketService.sellTicket(); } } public class RailwayStation implements TicketService { @Override public void sellTicket() { System.out.println("售票............"); } @Override public void inquire() { System.out.println("查询............"); } @Override public void withdraw() { System.out.println("退票............"); } } public interface TicketService { //售票 void sellTicket(); //问询 void inquire(); //退票 void withdraw(); }
分别建立Before、AfterReturn、Around、Throw四个Advice数据结构
public class TicketServiceAfterReturningAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("AFTER_RETURNING:本次服务已结束...."); } } public class TicketServiceAroundAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("AROUND_ADVICE:BEGIN...."); Object returnValue = invocation.proceed(); System.out.println("AROUND_ADVICE:END....."); return returnValue; } } public class TicketServiceBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("BEFORE_ADVICE: 欢迎光临代售点...."); } } public class TicketServiceThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Exception ex) { System.out.println("AFTER_THROWING...."); } public void afterThrowing(Method method, Object[] args, Object target, Exception ex) { System.out.println("afterThrowing调用过程出错啦!!!!!"); } }
运行结果以下:ide
使用过程当中主要围绕ProxyFactoryBean,从类图中发现它继承了AdvisedSupport,AdvisedSupport数据结构以下:ui
经过ProxyFactoryBean配置完接口、真正被调用目标、Advice以后,使用proxyFactoryBean.getObject()生成代理对象,关键步骤是getProxy(createAopProxy())this
【ProxyFactoryBean】 private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. Class<?> targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); //建立CglibProxy 或 JdkProxy this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }
createAopProxy()具体作了什么呢,主要涉及到DefaultAopProxyFactory 、ObjenesisCglibAopProxy、JdkDynamicAopProxy、AopProxyFactory结合工厂+单例模式完成。spa
获取到具体的AopProxy以后,再经过aopProxy.getProxy执行准备工做,例如把Advice转换成MethodInterceptor等。3d
JdkDynamicAopProxy 和CglibAopProxy只是建立代理方式的两种方式而已,实际上咱们为方法调用添加的各类Advice的执行逻辑都是统一的。在Spring的底层,会把咱们定义的各个Adivce分别包裹成一个 MethodInterceptor,这些Advice按照加入Advised顺序,构成一个AdivseChain。代理
例如示例代码中添加四个Advice,在CglibProxy中分别使用AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter.getInterceptor(Advisor advisor)包装成新的MethodInterceptor。因为TicketServiceAroundAdvice继承了MethodInterceptor,因此不用适配。例如ThrowsAdviceAdaptercode
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof ThrowsAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { return new ThrowsAdviceInterceptor(advisor.getAdvice()); } }
再看看每一个拦截器作了什么。对象
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; /** * Create a new MethodBeforeAdviceInterceptor for the given advice. * @param advice the MethodBeforeAdvice to wrap */ public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { //在调用方法以前,先执行BeforeAdvice this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); } } public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { private final AfterReturningAdvice advice; /** * Create a new AfterReturningAdviceInterceptor for the given advice. * @param advice the AfterReturningAdvice to wrap */ public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { //先调用invocation Object retVal = mi.proceed(); //调用成功后,调用AfterReturningAdvice this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; } } public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice { private static final String AFTER_THROWING = "afterThrowing"; private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class); private final Object throwsAdvice; @Override public Object invoke(MethodInvocation mi) throws Throwable { //使用大的try,先执行代码,捕获异常 try { return mi.proceed(); } catch (Throwable ex) { //获取异常处理方法 Method handlerMethod = getExceptionHandler(ex); //调用异常处理方法 if (handlerMethod != null) { invokeHandlerMethod(mi, ex, handlerMethod); } throw ex; } } private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable { Object[] handlerArgs; if (method.getParameterTypes().length == 1) { handlerArgs = new Object[] { ex }; } else { handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex}; } try { method.invoke(this.throwsAdvice, handlerArgs); } catch (InvocationTargetException targetEx) { throw targetEx.getTargetException(); } } }
每一个拦截器会在不一样时刻执行本身的拦截逻辑,依据上图的拦截器顺序(After——Around——Before——Throw),图示说明调用关系。
若是只想拦截某个方法,能够手动建立PointcutAdvisor
//手动建立一个pointcut,专门拦截inquire方法 AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution( * inquire(..))"); proxyFactoryBean.addAdvisor(new FilteredAdvisor(pointcut,beforeAdvice)); private static class FilteredAdvisor implements PointcutAdvisor { private Pointcut pointcut; private Advice advice; public FilteredAdvisor(Pointcut pointcut, Advice advice) { this.pointcut = pointcut; this.advice = advice; } @Override public Pointcut getPointcut() { return pointcut; } @Override public Advice getAdvice() { return advice; } @Override public boolean isPerInstance() { return false; } }
Spring处理该PointcutAdvisor是在DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法中
首先会获取FilterAdvisor里PointCut的MethodMatcher,这里包含"execution( * inquire(..))"表达式,和入参里的method比较是否一致,因为TicketService有sellTicket、inquire、withdraw,因此MethodMatcher会比较三次,只有inquire能经过,组装成一个InterceptorAndDynamicMethodMatcher,交给ReflectiveMethodInvocation。因此只有执行inquire方法会出现before拦截,其余方法正常执行。