Análisis de código fuente del método de anotación Spring AOP

Análisis de código fuente del método de anotación Spring AOP

Programación de tecnología Java TSMYK

Prefacio

En el último artículo Explicación detallada del uso de la función Spring AOP, aprendí un uso detallado de Sprig AOP. Ahora veamos cómo se implementa en Spring.

Aspectj-autoproxy

Sabemos que si desea utilizar Spring AOP, primero debe agregar el elemento de configuración <aop: aspectj-autoproxy expose-proxy = "true" proxy-target-class = "true" /> en el archivo de configuración, y los dos los atributos son opcionales. Para cada etiqueta en Spring, hay un analizador correspondiente para el análisis, y para las etiquetas aspectj-autoproxy, el analizador AspectJAutoProxyBeanDefinitionParser se utiliza para analizar, como se muestra a continuación:


public class AopNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        // 注册 aspectj-autoproxy 标签的解析器
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

Hay dos funciones principales en AspectJAutoProxyBeanDefinitionParser. Una es registrar el bean AnnotationAwareAspectJAutoProxyCreator, y la otra es analizar los dos atributos de <aop: aspectj-autoproxy />. Entre ellos, la función de AOP la realiza básicamente AnnotationAwareAspectJAutoProxyCreator;

Registrar AnnotationAwareAspectJAutoProxyCreator

Todos los analizadores implementan la interfaz BeanDefinitionParser, y la entrada se analiza desde el método de análisis. El método de análisis de AspectJAutoProxyBeanDefinitionParser es el siguiente:


class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 注册AnnotationAwareAspectJAutoProxyCreator bean 和处理标签的两个属性
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        // 处理子标签
        extendBeanDefinition(element, parserContext);
        return null;
    }
}

El método AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNeeded es el siguiente:


public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    // 注册 AnnotationAwareAspectJAutoProxyCreator
    BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 解析标签的两个属性expose-proxy 和 proxy-target-class
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // 注册组件并通知,便于监听器进一步处理,这里可以不用看
    registerComponentIfNecessary(beanDefinition, parserContext);
}

En este método, se completan principalmente tres funciones y cada línea de código completa una función:

  1. Registrar AnnotationAwareAspectJAutoProxyCreator
  2. Procesamiento de atributos de clase de destino y de proxy de exposición
  3. Registrar componentes y notificar

    Registrar AnnotationAwareAspectJAutoProxyCreator


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
// 注册
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
    //如果已经注册且与现在的不一致,则需要根据优先级来判断到底需要使用哪一个
    //AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        // 如果缓存中和现在注册的class不一样
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            // 判断优先级,如果现在的优先级比缓存中的大,则取现在的这个
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        //如果相同,则无需再创建
        return null;
    }
    // 如果还没有注册,则进行注册
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 注册
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

Procesamiento de atributos de clase de destino y de proxy de exposición


处理 expose-proxy 和 proxy-target-class 属性

private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry,Element sourceElement) {
    if (sourceElement != null) {
        // 获取proxy-target-class的值
        boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
        if (proxyTargetClass) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
        // 获取 expose-proxy的值
        boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
        if (exposeProxy) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
        }
    }
}
//设置属性 proxyTargetClass 为true
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
    }
}
//设置属性 exposeProxy为true
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
    }
}

En este punto, se completa el registro de AnnotationAwareAspectJAutoProxyCreator. Como se mencionó anteriormente, las funciones de AOP son básicamente completadas por AnnotationAwareAspectJAutoProxyCreator. A continuación, echemos un vistazo a cómo esta clase completa las operaciones de AOP.

Parse Advce

Echemos un vistazo al diagrama de clases de AnnotationAwareAspectJAutoProxyCreator de la siguiente manera:

Análisis de código fuente del método de anotación Spring AOP
Como se puede ver en el diagrama de clases anterior, AnnotationAwareAspectJAutoProxyCreator implementa BeanPostProcessor, y el bean de esta interfaz se implementa en Spring. Cuando Spring carga el bean, llamará a su método postProcessAfterInitializatio antes de la inicialización; se implementa el método postProcessAfterInitialization de la clase padre AbstractAutoProxyCreator como sigue:


public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean != null) {
        // 根据beanClass 和 beanName 创建缓存的 key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 如果该bean适合被代理,则必须包装
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
// 包装bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 如果已经处理过,则直接返回
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 该bean无需增强,则直接返回
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    //如果bean是Advice.class, Pointcut.class, Advisor.class, AopInfrastructureBean.class, 则直接返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        // 添加该bean不需要增强的标志到缓存中
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 获取bean所有的增强
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    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;
}

A partir del código anterior, podemos ver que la mejora de AOP se analizará antes de crear una instancia de AnnotationAwareAspectJAutoProxyCreator. Después de que se mejore el análisis, se creará el proxy mejorado; este artículo analizará primero la adquisición mejorada y la creación del proxy será hecho en el siguiente artículo explica.

Mejora

Obtenga todas sus mejoras de acuerdo con la clase correspondiente del bean y el beanName, para el método getAdvicesAndAdvisorsForBean ()


protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
    // 找出所有符合条件的增强
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

findEligibleAdvisors () lig:


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取所有增强
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 获取所有增强中适用于 bean 的增强并应用
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对增强进行扩展和排序
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

El método para obtener todas las mejoras findCandidateAdvisors () Después de muchos juicios lógicos complicados, la adquisición mejorada de AOP y el análisis de expresiones de corte de puntos se implementan dentro de este método:


protected List<Advisor> findCandidateAdvisors() {
    // 调用父类方法加载配置文件中的AOP声明
    List<Advisor> advisors = super.findCandidateAdvisors();
    // 创建所有AspectJ增强
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}
//父类 findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
    return this.advisorRetrievalHelper.findAdvisorBeans();
}
// 寻找所有符合增强的bean,this.advisorRetrievalHelper.findAdvisorBeans
public List<Advisor> findAdvisorBeans() {
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 寻找Advisor注解的beanName
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        // 该bean符合增强
        if (isEligibleBean(name)) {
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                // 该bean正创建,则忽略
            }
            else {
                advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
        }
    }
    return advisors;
}

Obtenga la mejora de anotación del bean, correspondiente al método this.aspectJAdvisorsBuilder.buildAspectJAdvisors (), busque todos los beans anotados de AspectJ, para cada método de mejora, se creará un Asesor correspondiente, es decir, un método para un Asesor


// 查找所有 AspectJ 注解的bean,对于每一个增强方法,都会创建对应的Advisor,即一个方法对于一个Advisor
public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;
    // .... 省略一些null判断
    List<Advisor> advisors = new ArrayList<>();
    aspectNames = new ArrayList<>();
    // 获取所有的 beanName
    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
    for (String beanName : beanNames) {
        // 如果该 bean不符合条件,则跳过
        if (!isEligibleBean(beanName)) {
            continue;
        }
        Class<?> beanType = this.beanFactory.getType(beanName);
        // 如果该 bean 存在 Aspect 注解
        if (this.advisorFactory.isAspect(beanType)) {
            aspectNames.add(beanName);
            // 根据beanType和beanName创建AspectMetadata ,表示增强的元数据
            AspectMetadata amd = new AspectMetadata(beanType, beanName);
            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                // 解析标记了 AspectJ 注解中的增强方法
                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                if (this.beanFactory.isSingleton(beanName)) {
                    // 如果该 bean是单例,则直接把解析到增强方法放到缓存中
                    this.advisorsCache.put(beanName, classAdvisors);
                }else {
                    //否则把对于的工厂放到缓存中
                    this.aspectFactoryCache.put(beanName, factory);
                }
                advisors.addAll(classAdvisors);
             }else {
                tadataAwareAspectInstanceFactory factory =new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                this.aspectFactoryCache.put(beanName, factory);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
            }
        }
    }
    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    // 记录缓存
    List<Advisor> advisors = new ArrayList<>();
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            advisors.addAll(cachedAdvisors);
        }
        else {
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    return advisors;
}

El método anterior ha completado la extracción del asesor y la adquisición del potenciador se transfiere al método advisorFactory.getAdvisors (), de la siguiente manera:


public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    //获取标记为 AspectJ 的类
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    // 获取name
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    //验证aspectClass 
    validate(aspectClass);

    //AOP 可以将增强延迟初始化,这里使用装饰器对工厂将包装
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

    List<Advisor> advisors = new ArrayList<>();
    // 处理每个增强方法,getAdvisorMethods 返回该增强类的所有增强方法
    for (Method method : getAdvisorMethods(aspectClass)) {
        // 每个方法对应一个 advisor
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    // 如果寻找的增强器不为空且配置了增强延迟初始化,那么需要在首位添加同步实例化增强器
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }

    // 获取 DeclareParents 注解
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }
    return advisors;
}

//获取增强类的所有增强方法 getAdvisorMethods 
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
    final List<Method> methods = new ArrayList<>();
    ReflectionUtils.doWithMethods(aspectClass, method -> {
        // 排除掉 Pointcut 方法
        if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
            methods.add(method);
        }
    });
    methods.sort(METHOD_COMPARATOR);
    return methods;
}

Obtención de potenciadores ordinarios

El potenciador normal se obtiene mediante el método getAdvisor (), que incluye la adquisición de anotaciones puntuales y la mejora de la generación de información de anotaciones, de la siguiente manera:


public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
    // 切点信息的获取,如@After, @Before
    AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    // 根据切点信息,生成不同的增强器
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

Obtenga información sobre el punto de corte getPonitcut:


private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    // 获取方法上的注解
    AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    // 使用 AspectJExpressionPointcut 封装切点信息
    AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
    // 设置切点表达式如:execution(* *Service*(..))
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
    if (this.beanFactory != null) {
        ajexp.setBeanFactory(this.beanFactory);
    }
    return ajexp;
}

// 获取方法上的注解 findAspectJAnnotationOnMethod
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
    // ASPECTJ_ANNOTATION_CLASSES 是一个数组:{Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}
    for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
        AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
        if (foundAnnotation != null) {
            return foundAnnotation;
        }
    }
    return null;
}
// 获取注解
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
    A result = AnnotationUtils.findAnnotation(method, toLookFor);
    if (result != null) {
        return new AspectJAnnotation<>(result);
    }
    else {
        return null;
    }
}

Una vez que el método anterior obtiene la información específica de pointcut, generará el potenciador correspondiente de acuerdo con la información de pointcut. Cada información de pointcut como @After, @Before corresponde a un objeto InstantiationModelAwarePointcutAdvisorImpl, de la siguiente manera:


new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName)

En el proceso de instanciar el objeto, hay algunos procesos de asignación. Además, de acuerdo con los diferentes tipos de mejora, como @After, @Before, es necesario crear diferentes mejoradores, como se muestra a continuación:


public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
        Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    // .... 一些属性的赋值操作
    // A singleton aspect.
    this.pointcut = this.declaredPointcut;
    this.lazy = false;
    this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);

}

El método instantiateAdvice es el siguiente, que creará diferentes potenciadores basados ​​en diferentes anotaciones mejoradas:


private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return (advice != null ? advice : EMPTY_ADVICE);
}

// 创建不同的增强器
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    // 获取 Aspect 注解对应的class
    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
    // 再次获取Aspect注解类的所有增强方法来进行判断
    AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }
    // 最终的增强器
    AbstractAspectJAdvice springAdvice;
    // 根据注解类型创建不同的增强器
    switch (aspectJAnnotation.getAnnotationType()) {
        // Pointcut注解 不处理
        case AtPointcut:
            return null;
        case AtAround:
            // around 注解,对应AspectJAroundAdvice增强器
            springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore:
            // Before注解,对应AspectJMethodBeforeAdvice增强器
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
           // After注解,对应AspectJAfterAdvice增强器
            springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
             // AfterReturning注解,对应AfterReturning增强器
            springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            // 设置返回值
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            // AtAfterThrowing注解,对应AspectJAfterThrowingAdvice增强器
            springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            // 设置对应的异常
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
    }

    // 对获取到增强器进行一些配置
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}

A continuación, observe la implementación del potenciador:

El potenciador AspectJMethodBeforeAdvice correspondiente a la anotación @Before:


springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {

    public AspectJMethodBeforeAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJBeforeAdviceMethod, pointcut, aif);
    } 
    // before 方法
    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        invokeAdviceMethod(getJoinPointMatch(), null, null);
    }
    // .......
}
// invokeAdviceMethod 方法
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex){
        return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}
// invokeAdviceMethodWithGivenArgs 方法:
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
    Object[] actualArgs = args;
    if (this.aspectJAdviceMethod.getParameterCount() == 0) {
        actualArgs = null;
    }
    ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
    // 激活增强方法
    return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);

}

Los diferentes tipos de mejoradores mencionados anteriormente son todas subclases de AbstractAspectJAdvice y eventualmente desactivarán el método de mejora en el método invokeAdviceMethod de esta clase.

La lógica del método anterior ha completado el análisis de todos los potenciadores, pero para todos los potenciadores, no necesariamente aplicable al bean actual, por lo que debe seleccionar un potenciador adecuado.

Este es el segundo paso del método findEligibleAdvisors anterior, el método findAdvisorsThatCanApply:


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取所有增强
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 获取所有增强中适用于 bean 的增强并应用
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对增强进行扩展和排序
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

findAdvisorsThatCanApply 方法 :


protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 过滤已经得到的 advisors
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    for (Advisor candidate : candidateAdvisors) {
        // 首先处理引介增强
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // 上面已经处理过了
            continue;
        }
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

La función principal de findAdvisorsThatCanApply es determinar si la mejora es aplicable al bean actual basándose en el beanClass y las mejoras del método. El método correspondiente es canAppley (), de la siguiente manera:


public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    // 引介增强处理
    if (advisor instanceof IntroductionAdvisor) {
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }else if (advisor instanceof PointcutAdvisor) {
        // 一般增强处理
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }else {
        return true;
    }
}

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    // 不匹配,直接返回
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    // 判断方法是否匹配
    for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                    methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }
    return false;
}

Lo anterior es el análisis mejorado de Spring AOP, que incluye el análisis de la clase de anotación de aspecto y el análisis de todos los métodos mejorados de esta clase.

para resumir

Función Spring AOP, la clase de análisis correspondiente implementa la interfaz BeanPostProcessor, que nos permite realizar algunas operaciones en el bean antes de la inicialización del bean. Para AOP anotado, antes de instanciar el bean AnnotationAwareAspectJAutoProxyCreator, resolverá la clase anotada de Aspect. métodos de mejora en esta clase, cada método de mejora corresponde a un asesor.Cuando el asesor se obtiene analizando el método de mejora, se crearán diferentes mejoradores de acuerdo con los diferentes tipos de anotaciones del método.

Lo anterior presenta principalmente cómo obtener el enhancer correspondiente al bean. Sabemos que Spring AOP se implementa a través de proxy dinámico. Luego de obtener el enhancer, puedes crear el proxy correspondiente. Sobre la creación del proxy, se presentará el siguiente artículo.

Supongo que te gusta

Origin blog.51cto.com/15077536/2608535
Recomendado
Clasificación