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();
            }
  • 相关阅读:
    Gin框架系列02:路由与参数
    Gin框架系列01:极速上手
    Go语言库系列之email
    Go语言库系列之aurora
    Go语言库系列之dotsql
    Go语言库系列之flag
    Go解算法07整数反转
    Go语言micro之快速搭建微服务
    理解Golang组件protobuf
    理解Go语言组件flag
  • 原文地址:https://www.cnblogs.com/linlf03/p/11217662.html
Copyright © 2011-2022 走看看