美文网首页
2021-03-31_SpringAspectJ源码学习笔记

2021-03-31_SpringAspectJ源码学习笔记

作者: kikop | 来源:发表于2021-04-01 08:53 被阅读0次

SpringAspectJ源码学习笔记

1概述

AOP现有两个主要的流行框架,即Spring AOP和Spring+AspectJ。前者SpringAOP使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供基于接口的代理,不支持类的代理。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

AOP(Aspect OrientedProgramming, 面向切面/方面编程) 旨在从业务逻辑中分离出来横切逻辑【eg:性能监控、日志记录、权限控制等】,提高模块化,即通过AOP解决代码耦合问题,让职责更加单一。

本节主要学习下基于注解的使用方式,首先看一下代码如何实现,接着基于源码剖析。

下图来源于网络

[图片上传失败...(image-496a8a-1617238323884)]

1.1AspectJ源码分析步骤

  1. EnableAspectJAutoProxy注解分析
  2. AopConfigUtils功能
  3. 代理对象BeanDefinition的产生时序
  4. 代理对象实例创建时序
  5. 业务方法的调用

2代码示例

2.1基于配置(本节不扩展)

2.2基于注解(重点)

2.2.1maven依赖

<!--springframework-->
<springframework.version>5.0.0.RELEASE</springframework.version>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>technicalskill</artifactId>
        <groupId>com.kikop</groupId>
        <version>1.0-SNAPSHOT</version>
        <!--定义依赖的父pom文件-->
        <relativePath>../pom.xml</relativePath>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>myspringaspectjdemo</artifactId>

    <properties>
    </properties>

    <dependencies>

        <!--1.techcommon-->
        <dependency>
            <groupId>com.kikop</groupId>
            <artifactId>techcommon</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


        <!--2.springframework-->

        <!--2.spring对web的支持,依赖 spring-webmvc-->
        <!--全家桶,此时jar包会自动下载(spring-context、spring-web、spring-webmvc)-->
        <!--<dependency>-->
        <!--<groupId>org.springframework</groupId>-->
        <!--<artifactId>spring-webmvc</artifactId>-->
        <!--<version>${springframework.version}</version>-->
        <!--</dependency>-->

        <!--2.1.spring-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <!--2.2.spring-context-support-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <!--2.3.spring 动态代理依赖(aop 和 aspect)-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <!--2.4.spring-aspects内部依赖:aspectjweaver1.8.11,集成了aopalliance源码-->
        <!--springframewrok4或单独使用aspectjweaver,需手动添加:aopalliance依赖包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <!--2.5.spring test相关依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${springframework.version}</version>
        </dependency>

    </dependencies>
</project>

2.2.2定义业务服务类

package com.kikop.myspringaspectj.service;

import org.springframework.stereotype.Service;

/**
 * @author kikop
 * @version 1.0
 * @project Name: myspringaspectjdemo
 * @file Name: LogService
 * @desc LogService
 * @date 2021/3/31
 * @time 10:50
 * @by IDE: IntelliJ IDEA
 */
@Service(value = "logService")
public class LogService {

    public LogService() {
    }

    public String getLogInfo() {
        String result = "增加一个日志记录";
        System.out.println(result);
        return result;
    }
}

2.2.3切面定义

package com.kikop.myspringaspectj.myaspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @author kikop
 * @version 1.0
 * @project Name: myspringaspectjdemo
 * @file Name: MyLogAspect
 * @desc MyLogAspect
 * @date 2021/3/31
 * @time 10:50
 * @by IDE: IntelliJ IDEA
 */
// 注意点1
@Aspect
@Component
public class MyLogAspect {

    /**
     * 定义方法切点函数(设置需要拦截的范围)
     */
    @Pointcut("execution(* com.kikop.myspringaspectj..*.*(..))")
    private void myLogPointCut() {

    }

    /**
     * 定义环绕增强逻辑
     *
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("myLogPointCut()")
    public Object invoke(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("begin log...");
        Object result = proceedingJoinPoint.proceed();
        System.out.println("end log.");
        return result;
    }
}

2.2.4配置定义

package com.kikop.myspringaspectj.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @author kikop
 * @version 1.0
 * @project Name: myspringaspectjdemo
 * @file Name: AppConfig
 * @desc AppConfig
 * @date 2021/3/31
 * @time 10:50
 * @by IDE: IntelliJ IDEA
 */
@Configuration
@ComponentScan("com.kikop.myspringaspectj")

// 注意点2
// 开启AspectJ注解代理
@EnableAspectJAutoProxy
public class AppConfig {
}

2.2.5测试

package com.kikop.myspringaspectj;

import com.kikop.myspringaspectj.config.AppConfig;
import com.kikop.myspringaspectj.service.LogService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


/**
 * @author kikop
 * @version 1.0
 * @project Name: myspringaspectjdemo
 * @file Name: aspectjTest
 * @desc aspectjTest
 * @date 2021/3/31
 * @time 10:50
 * @by IDE: IntelliJ IDEA
 */
public class aspectjTest {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        LogService logService = annotationConfigApplicationContext.getBean("logService", LogService.class);
        logService.getLogInfo();
    }
}

输出如下:

begin log...
增加一个日志记录
end log.

3源码分析

3.1EnableAspectJAutoProxy注解分析

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

核心是这个注解引入了一个 @Import,value为AspectJ实现的一个ImportBeanDefinitionRegistrar,该接口需实现:registerBeanDefinitions,用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator。

/**
 * Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
 * AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry}
 * as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see EnableAspectJAutoProxy
 */
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }

3.2AopConfigUtils功能

该Utils用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator。

// org\springframework\aop\config\AopConfigUtils.java
/**
 * The bean name of the internally managed auto-proxy creator.
 */
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
      "org.springframework.aop.config.internalAutoProxyCreator";
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
   return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
      @Nullable Object source) {

   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
      @Nullable Object source) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

   if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      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);
   // 设置aop优先级最高(最小值) 
   beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
   beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
   return beanDefinition;
}

3.3代理对象的BeanDefinition产生时序

3.3.1Step1_AnnotationConfigApplicationContext_refresh

SpringIOC容器启动时

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh(); //step1
}
// this();
// 构造 BeanDefinitionReader和BeanDefinitionScanner
public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

3.3.2Step2_AbstractApplicationContext_invokeBeanFactoryPostProcessors

接着来到BeanFactoryPostProcessors后置处理器。

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory); //step2

3.3.3Step3_ConfigurationClassPostProcessor

PostProcessorRegistrationDelegate.java-->ConfigurationClassPostProcessor.java

获取所有的configClasses,用于后面遍历

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
   List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
   String[] candidateNames = registry.getBeanDefinitionNames();

   for (String beanName : candidateNames) {
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
            ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
         if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
         }
      }
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
         configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
   }

   // Return immediately if no @Configuration classes were found
   if (configCandidates.isEmpty()) {
      return;
   }

   // Sort by previously determined @Order value, if applicable
   configCandidates.sort((bd1, bd2) -> {
      int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
      int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
      return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
   });

   // Detect any custom bean name generation strategy supplied through the enclosing application context
   SingletonBeanRegistry sbr = null;
   if (registry instanceof SingletonBeanRegistry) {
      sbr = (SingletonBeanRegistry) registry;
      if (!this.localBeanNameGeneratorSet) {
         BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
         if (generator != null) {
            this.componentScanBeanNameGenerator = generator;
            this.importBeanNameGenerator = generator;
         }
      }
   }

   if (this.environment == null) {
      this.environment = new StandardEnvironment();
   }

   // Parse each @Configuration class
   ConfigurationClassParser parser = new ConfigurationClassParser(
         this.metadataReaderFactory, this.problemReporter, this.environment,
         this.resourceLoader, this.componentScanBeanNameGenerator, registry);

   Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
   Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
   do {
      parser.parse(candidates);
      parser.validate();

      Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
      configClasses.removeAll(alreadyParsed);

      // Read the model and create bean definitions based on its content
      if (this.reader == null) {
         this.reader = new ConfigurationClassBeanDefinitionReader(
               registry, this.sourceExtractor, this.resourceLoader, this.environment,
               this.importBeanNameGenerator, parser.getImportRegistry());
      }
      this.reader.loadBeanDefinitions(configClasses);

3.3.4Step4_ConfigurationClassBeanDefinitionReader

遍历configClass

image-20210401080109472.png
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
   TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
   for (ConfigurationClass configClass : configurationModel) {
      loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
   }
}
/**
 * Read a particular {@link ConfigurationClass}, registering bean definitions
 * for the class itself and all of its {@link Bean} methods.
 */
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
      TrackedConditionEvaluator trackedConditionEvaluator) {
    
    loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
    // ConfigurationClass: beanName 'appConfig', com.kikop.myspringaspectj.config.AppConfig
    // 处理我们自定义的BeanDefinitionRegistrar
    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

3.3.5Step5_registerBeanDefinitions

开始真正的BeanDefinition注册。

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
   registrars.forEach((registrar, metadata) ->
         registrar.registerBeanDefinitions(metadata, this.registry));
}

3.3.6Step6_AspectJAutoProxyRegistrar

走过千山万水,回来了,用于向SpringIOC容器中注入一个Bean,名称为:org.springframework.aop.config.internalAutoProxyCreator

@Override
public void registerBeanDefinitions(
      AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

   AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

   AnnotationAttributes enableAspectJAutoProxy =
         AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
   if (enableAspectJAutoProxy != null) {
      if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
         AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
      }
      if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
         AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
      }
   }
}

3.4代理对象实例创建时序

image-20210401081415075.png

3.4.1Step1_AbstractApplicationContext_finishBeanFactoryInitialization

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

3.4.2Step2_DefaultListableBeanFactory_preInstantiateSingletons

0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
2 = "org.springframework.context.annotation.internalRequiredAnnotationProcessor"
3 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
4 = "org.springframework.context.event.internalEventListenerProcessor"
5 = "org.springframework.context.event.internalEventListenerFactory"
6 = "appConfig"
7 = "myLogAspect"
8 = "logService"
9 = "org.springframework.aop.config.internalAutoProxyCreator"
// 这里我们以logService分析    
if (this.logger.isDebugEnabled()) {
   this.logger.debug("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
                                ((SmartFactoryBean<?>) factory).isEagerInit(),
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);  // go on

3.4.3Step3_AbstractBeanFactory_createBean

// Create bean instance.
if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }

3.4.4Step4_AbstractAutowireCapableBeanFactory_createBean

// Initialize the bean instance.
Object exposedObject = bean;
try {
   populateBean(beanName, mbd, instanceWrapper);
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}

3.4.5Step5_AbstractAutowireCapableBeanFactory_initializeBean

这里涉及Bean的声明周期

/**
 * Initialize the given bean instance, applying factory callbacks
 * as well as init methods and bean post processors.
 * <p>Called from {@link #createBean} for traditionally defined beans,
 * and from {@link #initializeBean} for existing bean instances.
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean the new bean instance we may need to initialize
 * @param mbd the bean definition that the bean was created with
 * (can also be {@code null}, if given an existing bean instance)
 * @return the initialized bean instance (potentially wrapped)
 * @see BeanNameAware
 * @see BeanClassLoaderAware
 * @see BeanFactoryAware
 * @see #applyBeanPostProcessorsBeforeInitialization
 * @see #invokeInitMethods
 * @see #applyBeanPostProcessorsAfterInitialization
 */
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //step1:BeanNameAware
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }
    //step1:applyBeanPostProcessorsBeforeInitialization
   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   //step3:invokeInitMethods
   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   //step4:applyBeanPostProcessorsAfterInitialization
   // Bean实例化后,检查其是否需要走aop代理(JDK或CGLIB),里面有复杂的判断逻辑
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

3.4.6Step6_AbstractAutowireCapableBeanFactory_applyBeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
       // 这里的 beanProcessor就是3.3中创建的:AnnotationAwareAspectJAutoProxyCreator
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
image-20210401083413910.png

3.4.7Step7_AbstractAutoProxyCreator_postProcessAfterInitialization

这里判断Bean实例对象是否需要代理

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

getAdvicesAndAdvisorsForBean执行具体的判断逻辑,后续在结合execution执行主体进行深入分析。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    ......
    // Create proxy if we have advice.
        // getAdvicesAndAdvisorsForBean进行具体的判断逻辑,参数:
        // param1:com.kikop.myspringaspectj.service.LogService
        // param2:logService
        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;
        }
// aop\framework\autoproxy\AbstractAdvisorAutoProxyCreator.java
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

3.4.8Step7_DefaultAopProxyFactory_createAopProxy

至此,LogService代理对象创建完成

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      // targetClass:class com.kikop.myspringaspectj.service.LogService 
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config); // 走JDK
      }
      return new ObjenesisCglibAopProxy(config); // 走CGLIG
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

3.5业务方法调用流程

调用就很简单了。

4总结

参考

相关文章

网友评论

      本文标题:2021-03-31_SpringAspectJ源码学习笔记

      本文链接:https://www.haomeiwen.com/subject/tfgzhltx.html