触发通知
在為AopProxy 代理對(duì)象配置攔截器的實(shí)現(xiàn)中,有一個(gè)取得攔截器的配置過(guò)程,這個(gè)過(guò)程是由DefaultAdvisorChainFactory 實(shí)現(xiàn)的,這個(gè)工廠類負(fù)責(zé)生成攔截器鏈,在它的getInterceptorsAndDynamicInterceptionAdvice 方法中,有一個(gè)適配器和注冊(cè)過(guò)程,通過(guò)配置Spring 預(yù)先設(shè)計(jì)好的攔截器,Spring 加入了它對(duì)AOP 實(shí)現(xiàn)的處理。
/*** 從提供的配置實(shí)例config中獲取advisor列表,遍歷處理這些advisor.如果是IntroductionAdvisor,* 則判斷此Advisor能否應(yīng)用到目標(biāo)類targetClass上.如果是PointcutAdvisor,則判斷* 此Advisor能否應(yīng)用到目標(biāo)方法method上.將滿足條件的Advisor通過(guò)AdvisorAdaptor轉(zhuǎn)化成Interceptor列表返回.*/ @Override public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());//查看是否包含IntroductionAdvisorboolean hasIntroductions = hasMatchingIntroductions(config, actualClass);//這里實(shí)際上注冊(cè)一系列AdvisorAdapter,用于將Advisor轉(zhuǎn)化成MethodInterceptorAdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();for (Advisor advisor : config.getAdvisors()) {if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {//這個(gè)地方這兩個(gè)方法的位置可以互換下//將Advisor轉(zhuǎn)化成InterceptorMethodInterceptor[] interceptors = registry.getInterceptors(advisor);//檢查當(dāng)前advisor的pointcut是否可以匹配當(dāng)前方法MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {if (mm.isRuntime()) {// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}else {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList; }GlobalAdvisorAdapterRegistry 負(fù)責(zé)攔截器的適配和注冊(cè)過(guò)程。
public abstract class GlobalAdvisorAdapterRegistry {/*** Keep track of a single instance so we can return it to classes that request it.*/private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();/*** Return the singleton {@link DefaultAdvisorAdapterRegistry} instance.*/public static AdvisorAdapterRegistry getInstance() {return instance;}/*** Reset the singleton {@link DefaultAdvisorAdapterRegistry}, removing any* {@link AdvisorAdapterRegistry#registerAdvisorAdapter(AdvisorAdapter) registered}* adapters.*/static void reset() {instance = new DefaultAdvisorAdapterRegistry();}}而GlobalAdvisorAdapterRegistry 起到了適配器和單例模式的作用,提供了一個(gè)DefaultAdvisorAdapterRegistry,它用來(lái)完成各種通知的適配和注冊(cè)過(guò)程。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {private final List<AdvisorAdapter> adapters = new ArrayList<>(3);/*** Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.*/public DefaultAdvisorAdapterRegistry() {registerAdvisorAdapter(new MethodBeforeAdviceAdapter());registerAdvisorAdapter(new AfterReturningAdviceAdapter());registerAdvisorAdapter(new ThrowsAdviceAdapter());}@Overridepublic Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {if (adviceObject instanceof Advisor) {return (Advisor) adviceObject;}if (!(adviceObject instanceof Advice)) {throw new UnknownAdviceTypeException(adviceObject);}Advice advice = (Advice) adviceObject;if (advice instanceof MethodInterceptor) {// So well-known it doesn't even need an adapter.return new DefaultPointcutAdvisor(advice);}for (AdvisorAdapter adapter : this.adapters) {// Check that it is supported.if (adapter.supportsAdvice(advice)) {return new DefaultPointcutAdvisor(advice);}}throw new UnknownAdviceTypeException(advice);}@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<>(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()]);}@Overridepublic void registerAdvisorAdapter(AdvisorAdapter adapter) {this.adapters.add(adapter);}}DefaultAdvisorAdapterRegistry 設(shè)置了一系列的是配置,正是這些適配器的實(shí)現(xiàn),為Spring AOP 提供了編織能力。下面以MethodBeforeAdviceAdapter 為例,看具體的實(shí)現(xiàn):
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {@Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof MethodBeforeAdvice);}@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();return new MethodBeforeAdviceInterceptor(advice);}}Spring AOP 為了實(shí)現(xiàn)advice 的織入,設(shè)計(jì)了特定的攔截器對(duì)這些功能進(jìn)行了封裝。我們接著看MethodBeforeAdviceInterceptor 如何完成封裝的?
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;}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );return mi.proceed();}}可以看到,invoke 方法中,首先觸發(fā)了advice 的before 回調(diào),然后才是proceed。AfterReturningAdviceInterceptor 的源碼:
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;}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {Object retVal = mi.proceed();this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());return retVal;}}ThrowsAdviceInterceptor 的源碼:
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;} } private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {Object[] handlerArgs;if (method.getParameterCount() == 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();} }?
總結(jié)
- 上一篇: 调用代理方法
- 下一篇: 初探Spring MVC 请求处理流程