• spring5.0源码解析 Aop 04 配置通知器


    在整个 AopProxy代理对象拦截回调过程中,都是通过 ReflectiveMethodInvocation 类的 proceed方法,在这个方法中 我能可以拿到 所有的 interceptorOrInterceptionAdvice 。
    ReflectiveMethodInvocation 类的 proceed

    Object interceptorOrInterceptionAdvice =
    			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    
    • 1
    • 2

    在 ReflectiveMethodInvocation 的构造方法中可以看到

    protected ReflectiveMethodInvocation(
    			Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
    			@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
    
    		this.proxy = proxy;
    		this.target = target;
    		this.targetClass = targetClass;
    		this.method = BridgeMethodResolver.findBridgedMethod(method);
    		this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
    		// 拦截器 通过构造方法中传递过来
    		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    我们以 JdkDynamicAopProxy 向上推
    在 JdkDynamicAopProxy 中 invoke 方法中可以看到

    // advised 是从 参数  public JdkDynamicAopProxy(AdvisedSupport config) 中获取过来的
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    
    • 1
    • 2

    AdvisedSupport 类同事越是ProxyFactoryBean 的基类,
    在 AdvisedSupport 的 getInterceptorsAndDynamicInterceptionAdvice 我们可以看到 获取拦截器的实现

    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
    		// 使用 cache与获取已有的inteceptor 链,但是第一次还是要通过自己生成,生成之后 缓存到 methodCache中
    		MethodCacheKey cacheKey = new MethodCacheKey(method);
    		List<Object> cached = this.methodCache.get(cacheKey);
    		if (cached == null) {
    			// 从  advisorChainFactory 获取拦截器链
    			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
    					this, method, targetClass);
    			this.methodCache.put(cacheKey, cached);
    		}
    		return cached;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    DefaultAdvisorChainFactory

    获取拦截器链是通过 advisorChainFactory 来完成的,从名字上可以看出来 他是一个生成通知链的工厂,

    getInterceptorsAndDynamicInterceptionAdvice

    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.
    		// 为了保证顺序  Advisor适配器注册表的接口。
    		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
    		// 获取所有 Advisor
    		Advisor[] advisors = config.getAdvisors();
    		// 创建 一个拦截器 列表
    		List<Object> interceptorList = new ArrayList<>(advisors.length);
    		// 获取 目标对象的 类类型
    		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    		Boolean hasIntroductions = null;
    
    		for (Advisor advisor : advisors) {
    			// 是否为 切入点 的 advisor  PointcutAdvisor:和切点有关的Advisor
    			if (advisor instanceof PointcutAdvisor) {
    				// Add it conditionally.
    				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
    				//  class 匹配
    				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
    					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
    					boolean match;
    					if (mm instanceof IntroductionAwareMethodMatcher) {
    						if (hasIntroductions == null) {
    							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
    						}
    						// 方法匹配
    						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
    					}
    					else {
    						// 方法匹配
    						match = mm.matches(method, actualClass);
    					}
    					// 如果匹配 从 适配器 的 registry 获取拦截器
    					if (match) {
    						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
    						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));
    						}
    					}
    				}
    			}
    			// IntroductionAdvisor只能应用于类级别的拦截,只能使用Introduction型的Advice
    			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;
    	}
    
    • 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
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    ProxyFactoryBean .getObject

    从上面的代码可以看出 Advised 还是从 ProxyFactoryBean 中获取的, 在 ProxyFactoryBean 的 getObject 方法中对 Advised 做了初始化
    这篇文章对初始化通知链做了解析

    @Override
    	@Nullable
    	public Object getObject() throws BeansException {
    		// 初始化通知器链
    		initializeAdvisorChain();
    		// 这里对singleton和prititype类型进行了区分,生成对象的proxy
    		if (isSingleton()) {
    			return getSingletonInstance();
    		}
    		else {
    			if (this.targetName == null) {
    				logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +
    						"Enable prototype proxies by setting the 'targetName' property.");
    			}
    			return newPrototypeInstance();
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    从 ProxyFactoryBean 的 initializeAdvisorChain 方法中 可以看出 他是遍历 interceptorNames 通过 beanFactory 获取的adcvisor 对象,他继承了 BeanFactoryAware 在 initialize 阶段 获取到了 beanFactory

    spring5.0 源码解析 initializeBean

  • 相关阅读:
    任务调度xxljob的使用记录
    [SLAM] 数学基础
    生成网络论文阅读styleGAN1(一):论文速览
    OpenJDK17-JVM源码阅读-ZGC-并发标记
    【BUG】段错误
    LeetCode第304场周赛
    十四、综合项目(斗地主)
    (SpringBoot)第一章:Spring基本概念和核心思想
    Go 语言中,`rune(a)` 将 `a` 转换为 `rune` 类型
    AI计算机视觉进阶项目(一)——带口罩识别检测(3)
  • 原文地址:https://blog.csdn.net/qq_44808472/article/details/126274474