目录

两次匹配

Bean 后置处理器中的匹配

方法调用时的匹配

Bean后置处理器中Advisor匹配流程

方法调用时的匹配

Jdk

cglib

小小总结

Advisor 收集与排序

责任链执行过程


两次匹配

Bean 后置处理器中的匹配

在 Bean 初始化过程中,Spring 会通过 Bean 后置处理器(BeanPostProcessor)匹配出符合当前 Bean 类型的 Advisor。这一过程主要发生在 postProcessAfterInitialization 方法中。

  • 目的:确定当前 Bean 是否需要代理,以及使用哪些 Advisor。

  • 过程:

  • Spring 会调用 getAdvicesAndAdvisorsForBean 方法,查找所有候选的 Advisor。

  • 过滤出可以应用到当前 Bean 的 Advisor,并将其存储在一个缓存中(如 advisedBeans)。

方法调用时的匹配

在方法调用时,Spring 会根据当前调用的方法和目标对象的类型,从已经匹配的 Advisor 中进一步匹配出符合当前方法的 Advisor。

  • 目的:动态构建拦截器链,以便在方法执行时应用相应的拦截器。

  • 过程:

  • Spring 会调用 getInterceptorsAndDynamicInterceptionAdvice 方法,获取与当前方法匹配的拦截器。

  • 通过切点(Pointcut)进一步过滤出符合当前方法的 Advisor。

Bean后置处理器中Advisor匹配流程

这个流程主要是在spring容器的初始化阶段,下面详细解析一下postProcessAfterInitialization的源码,注释贴在代码上

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        // 根据bean.getClass()和beanName构建缓存key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        
        // 检查bean是否已经被处理
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 如果需要代理,就包装bean
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 已经处理过的bean直接返回
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    
    // 跳过特定bean的检查代码...
    
    // 为给定bean获取适用的Advisor - 关键步骤!
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    
    // 如果找到了合适的Advisor,创建代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理的核心方法
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}
@Override
protected Object[] getAdvicesAndAdvisorsForBean(
        Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

    // 查找匹配当前bean的Advisors
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取所有候选Advisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 过滤出可以应用到当前bean的Advisor
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 扩展点,子类可以添加自定义的Advisor
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        // 排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

方法调用时的匹配

Jdk
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    
    // 获取被代理的对象
    TargetSource targetSource = this.advised.getTargetSource();
    Object target = null;
    
    try {
        // ... 省略一些特殊方法处理逻辑 ...
        
        Object retVal;
        
        // 处理通用拦截器逻辑
        if (this.advised.exposeProxy) {
            // 设置代理到ThreadLocal
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        
        // 获取目标对象
        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);
        
        // 获取当前方法的拦截器链 - 这里构建责任链!
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        
        // 如果拦截器链为空,直接反射调用目标方法
        if (chain.isEmpty()) {
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        }
        else {
            // 创建方法调用对象,包含了拦截器链
            MethodInvocation invocation = new ReflectiveMethodInvocation(
                    proxy, target, method, args, targetClass, chain);
            
            // 执行责任链
            retVal = invocation.proceed();
        }
        
        // 返回结果处理
        return retVal;
    }
    // ... 异常处理和清理代码 ...
}

cglib
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    // ... 开头代码省略 ...
    
    // 获取目标对象
    target = targetSource.getTarget();
    Class<?> targetClass = (target != null ? target.getClass() : null);
    
    // 获取当前方法的拦截器链 - 责任链构建发生在这里!
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    
    Object retVal;
    
    // 如果没有拦截器,直接调用目标方法
    if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
        // ... 直接调用目标方法代码 ...
    }
    else {
        // 创建方法调用对象,包含拦截器链
        MethodInvocation invocation = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);
        
        // 执行拦截器链
        retVal = invocation.proceed();
    }
    
    // ... 返回处理代码 ...
    return retVal;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable 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;
}
小小总结

责任链不是在代理创建时构建的,而是在方法调用时动态构建,只为当前调用的方法构建相关的拦截器链,而不是为所有方法预先构建,通过 methodCache 缓存已构建的拦截器链,避免重复构建,根据方法和目标类在运行时判断哪些 Advisor 适用,形成调用链

Advisor 收集与排序
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
        Advised config, Method method, @Nullable Class<?> targetClass) {

    // 创建拦截器列表
    List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
    
    // 获取目标类
    Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    
    // 判断是否存在引介增强
    boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
    
    // 注册表,用于缓存结果
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

    // 遍历所有Advisor
    for (Advisor advisor : config.getAdvisors()) {
        if (advisor instanceof PointcutAdvisor) {
            // 处理PointcutAdvisor类型的Advisor
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                // 将Advisor转换为拦截器
                MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                boolean match;
                // 检查方法是否匹配
                if (mm instanceof IntroductionAwareMethodMatcher) {
                    match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                }
                else {
                    match = mm.matches(method, actualClass);
                }
                if (match) {
                    // 将Advisor转换成拦截器并添加到列表中
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    if (mm.isRuntime()) {
                        // 运行时匹配的处理
                        for (MethodInterceptor interceptor : interceptors) {
                            interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                        }
                    }
                    else {
                        // 直接添加到拦截器链
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
            }
        }
        else if (advisor instanceof IntroductionAdvisor) {
            // 处理IntroductionAdvisor
            // ... existing code ...
        }
        else {
            // 处理其他类型的Advisor
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }

    return interceptorList;
}
责任链执行过程
@Override
@Nullable
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;
        Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
        if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        }
        else {
            // 不匹配,跳过当前拦截器,继续下一个
            return proceed();
        }
    }
    else {
        // 执行普通拦截器
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

 

AdvisorAdapter 将不同类型的 Advisor 统一适配为 MethodInterceptor 

每个 Advisor 被转换为 MethodInterceptor 后,按顺序组成一个拦截器链,每个拦截器决定是执行自己的逻辑还是传递给下一个拦截器,会通过递增 currentInterceptorIndex 实现链的遍历,递归调用 proceed() 方法,实现责任传递

更多推荐