转载自:https://blog.csdn.net/luanlouis/article/details/51155821
1、Spring内部创建代理对象的过程 在Spring的底层,如果配置了AOP,Spring会为每一个Bean创建一个对应的ProxyFactoryBean的FactoryBean来创建某个对象的代理对象。 假定有一个接口TicketService及其实现类RailwayStation,打算创建一个代理类,在执行TicketService的方法时的各个阶段,插入对应的业务代码。
1 2 3 4 5 6 7 8 9 10 public interface TicketService { public void sellTicket () ; public void inquire () ; public void withdraw () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 public class RailwayStation implements TicketService { public void sellTicket () { System.out.println("售票............" ); } public void inquire () { System.out.println("问询............." ); } public void withdraw () { System.out.println("退票............." ); } }
1 2 3 4 5 6 public class TicketServiceBeforeAdvice implements MethodBeforeAdvice { public void before (Method method, Object[] args, Object target) throws Throwable { System.out.println("BEFORE_ADVICE: 欢迎光临代售点...." ); } }
1 2 3 4 5 6 public class TicketServiceAfterReturningAdvice implements AfterReturningAdvice { @Override public void afterReturning (Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("AFTER_RETURNING:本次服务已结束...." ); } }
1 2 3 4 5 6 7 8 9 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; } }
1 2 3 4 5 6 7 8 9 10 11 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("调用过程出错啦!!!!!" ); } }
然后来手动使用ProxyFactoryBean来创建Proxy对象,并将相应的几种不同的Advice加入这个proxy对应的各个执行阶段中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public static void main (String[] args) { Advice beforeAdvice = new TicketServiceBeforeAdvice (); Advice afterReturningAdvice = new TicketServiceAfterReturningAdvice (); Advice aroundAdvice = new TicketServiceAroundAdvice (); Advice throwsAdvice = new TicketServiceThrowsAdvice (); RailwayStation railwayStation = new RailwayStation (); ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean (); proxyFactoryBean.setInterfaces(TicketService.class); proxyFactoryBean.setTarget(railwayStation); proxyFactoryBean.setProxyTargetClass(false ); proxyFactoryBean.addAdvice(afterReturningAdvice); proxyFactoryBean.addAdvice(aroundAdvice); proxyFactoryBean.addAdvice(throwsAdvice); proxyFactoryBean.addAdvice(beforeAdvice); TicketService ticketService = (TicketService) proxyFactoryBean.getObject(); ticketService.sellTicket(); }
运行结果:
1 2 3 4 5 AROUND_ADVICE:BEGIN.... BEFORE_ADVICE: 欢迎光临代售点.... 售票............ AROUND_ADVICE:END..... AFTER_RETURNING:本次服务已结束....
我们成功地创建了一个通过一个ProxyFactoryBean和真实的实例对象创建出了对应的代理对象,并将各个Advice加入到proxy代理对象中。
2、Spring AOP的核心ProxyFactoryBean 上面通过了使用ProxyFactoryBean实现了AOP的功能,在使用时通过addAdvice(Advice advice)把各类Advice添加到ProxyFactoryBean(实际是父类AdvisedSupport)中:
1 2 3 4 public void addAdvice (Advice advice) throws AopConfigException { int pos = this .advisors.size(); addAdvice(pos, advice); }
AdvisedSupport中维护了private List<Advisor> advisors = new LinkedList<Advisor>();列表,addAdvice中会把advice包装为DefaultPointcutAdvisor加入到这个列表里。 也就是说ProxyFactoryBean知道Advice信息,可以根据特定的类名和方法名返回对应的AdviceChain,用以表示需要执行的Advice串。当使用proxy时,对proxy对象调用的方法,都最终被转到这个类的invoke()方法中。以JdkDynamicAopProxy为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 final class JdkDynamicAopProxy implements AopProxy , InvocationHandler, Serializable { private final AdvisedSupport advised; @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null ; boolean setProxyContext = false ; TargetSource targetSource = this .advised.targetSource; Class<?> targetClass = null ; Object target = null ; try { Object retVal; List<Object> chain = this .advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); if (chain.isEmpty()) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { invocation = new ReflectiveMethodInvocation (proxy, target, method, args, targetClass, chain); retVal = invocation.proceed(); } return retVal; } finally { } } }
来看关键的getInterceptorsAndDynamicInterceptionAdvice函数:
1 2 3 4 5 6 7 8 9 10 public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }
最终是调用到了DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public List<Object> getInterceptorsAndDynamicInterceptionAdvice ( Advised config, Method method, Class<?> targetClass) { List<Object> interceptorList = new ArrayList <Object>(config.getAdvisors().length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); for (Advisor advisor : config.getAdvisors()) { if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher (interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { } else { } } return interceptorList; }
代码比较长,主要看for循环的第一个if分支。config.getAdvisors()返回的就是之前通过addAdvisor添加的Advisor列表(new DefaultPointcutAdvisor(advice))。registry.getInterceptors(advisor)是把advisor转换成MethodInterceptor[]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList <MethodInterceptor>(3 ); Advice advice = advisor.getAdvice(); if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } for (AdvisorAdapter adapter : this .adapters) { if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if (interceptors.isEmpty()) { throw new UnknownAdviceTypeException (advisor.getAdvice()); } return interceptors.toArray(new MethodInterceptor [interceptors.size()]); }
AdvisorAdapter的实例有AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter分别用于转换AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice为AfterReturningAdviceInterceptor、MethodBeforeAdviceInterceptor、ThrowsAdviceInterceptor。注意,示例代码里的TicketServiceAroundAdvice类是MethodInterceptor的子类,不需要AdvisorAdapter转换。
这里创建MethodInterceptor链,然后构造ReflectiveMethodInvocation实例,调用proceed():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Override public Object proceed () throws Throwable { if (this .currentInterceptorIndex == this .interceptorsAndDynamicMethodMatchers.size() - 1 ) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this .interceptorsAndDynamicMethodMatchers.get(++this .currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this .method, this .targetClass, this .arguments)) { return dm.interceptor.invoke(this ); } else { return proceed(); } } else { return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this ); } }
初始时,this.currentInterceptorIndex=-1,this.interceptorsAndDynamicMethodMatchers即先前创建的MethodInterceptor[]。 第一步,取MethodInterceptor[]中的第0个,即AfterReturningAdviceInterceptor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class AfterReturningAdviceInterceptor implements MethodInterceptor , AfterAdvice, Serializable { private final AfterReturningAdvice advice; public AfterReturningAdviceInterceptor (AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null" ); this .advice = advice; } @Override public Object invoke (MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); this .advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; } }
先执行mi.proceed(),即ReflectiveMethodInvocation实例的proceed()方法,进入proceed()后,取MethodInterceptor[]中的第1个,即TicketServiceAroundAdvice:
1 2 3 4 5 6 7 8 9 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; } }
同理再次进入proceed()后,取MethodInterceptor[]中的第2个,即ThrowsAdviceInterceptor:
1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } catch (Throwable ex) { Method handlerMethod = getExceptionHandler(ex); if (handlerMethod != null) { invokeHandlerMethod(mi, ex, handlerMethod); } throw ex; } }
之后进入proceed()后,取MethodInterceptor[]中的第3个,MethodBeforeAdviceInterceptor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); } }
之后进入proceed(),this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1满足条件,进入invokeJoinpoint:
1 2 3 protected Object invokeJoinpoint() throws Throwable { return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); }
这里执行被代理对象的方法调用。然后根据方法栈的调用依次执行完MethodBeforeAdviceInterceptor->ThrowsAdviceInterceptor->TicketServiceAroundAdvice->AfterReturningAdviceInterceptor。所以最终的运行情况是:
1 2 3 4 5 AROUND_ADVICE:BEGIN.... BEFORE_ADVICE: 欢迎光临代售点.... 售票............ AROUND_ADVICE:END..... AFTER_RETURNING:本次服务已结束....