zoukankan      html  css  js  c++  java
  • JdkDynamicAopProxy 拦截器链的获得与递归执行

    JdkDynamicAopProxy类的invoke方法

    1、获得拦截器链

    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    

      进入方法

    	/**
    	 * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
    	 * for the given method, based on this configuration.
    	 * @param method the proxied method
    	 * @param targetClass the target class
    	 * @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
    	 */
    	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;
    	}
    

      

    然后进入getInterceptorsAndDynamicInterceptionAdvice方法

    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
    			Advised config, Method method, 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<Object>(config.getAdvisors().length);
    		boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
    		AdvisorAdapterRegistry 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(targetClass)) {
    					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
    					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
    					if (MethodMatchers.matches(mm, method, targetClass, 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(targetClass)) {
    					Interceptor[] interceptors = registry.getInterceptors(advisor);
    					interceptorList.addAll(Arrays.asList(interceptors));
    				}
    			}
    			else {
    				Interceptor[] interceptors = registry.getInterceptors(advisor);
    				interceptorList.addAll(Arrays.asList(interceptors));
    			}
    		}
    		return interceptorList;
    	}
    

     

    2、递归

    proceed方法

    进入proceed方法

    目标方法执行之前的一系列的逻辑。

    public Object proceed() throws Throwable {
    		//	We start with an index of -1 and increment early.
    		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    			return invokeJoinpoint();
    		}
    
    		Object interceptorOrInterceptionAdvice =
    		    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    			// Evaluate dynamic method matcher here: static part will already have
    			// been evaluated and found to match.
    			InterceptorAndDynamicMethodMatcher dm =
    			    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
    			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
    				return dm.interceptor.invoke(this);
    			}
    			else {
    				// Dynamic matching failed.
    				// Skip this interceptor and invoke the next in the chain.
    				return proceed();
    			}
    		}
    		else {
    			// It's an interceptor, so we just invoke it: The pointcut will have
    			// been evaluated statically before this object was constructed.
    			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    		}
    	}
    

      

    所有的拦截器执行完毕后,执行invokeJoinpoint,调用目标方法

    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                return invokeJoinpoint();
            }
    

      

    至此,AOP的内容结束了。

     

    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                return invokeJoinpoint();
            }
  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/linlf03/p/11217662.html
Copyright © 2011-2022 走看看