Spring AOP切面原理
核心注解@EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
核心导入了AspectJAutoProxyRegistrar组件,进一步分析AspectJAutoProxyRegistrar组件
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);
			}
		}
	}
}
发现AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口
ImportBeanDefinitionRegistrar是Spring提供来用于自动装配的接口 核心方法有2个主要是传入扫描类的注解信息,Spring的BeanDefinitionRegistry 通过这个registry可以注册组件
public interface ImportBeanDefinitionRegistrar {
    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
			BeanNameGenerator importBeanNameGenerator) {
		registerBeanDefinitions(importingClassMetadata, registry);
	}
    
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
	}
}
明白了 BeanDefinitionRegistry 的作用进一步研究这个方法是AOP实现的核心AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
又调用了AOPConfigUtils的内部方法最终追踪到
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册AnnotationAwareAspectJAutoProxyCreator bean定义信息
   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 首先判断一下bean工厂里面有没有 AUTO_PROXY_CREATOR_BEAN_NAME这个bean 真实名称叫org.springframework.aop.config.internalAutoProxyCreator 第一次进来肯定没有
		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;
		}
// 开始创建bean
		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;
	}
- 判断工厂中是否已经存在org.springframework.aop.config.internalAutoProxyCreator这个bean定义信息
- 没有开始创建并注册调用 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
- beanDefinition 需要注册一个AnnotationAwareAspectJAutoProxyCreator的组件
- 进入DefaultListableBeanFactory#registerBeanDefinition方法 此处执行完毕之后bean工厂中已经加入了名称为org.springframework.aop.config.internalAutoProxyCreator且类型为AnnotationAwareAspectJAutoProxyCreator的BeanDefinition信息,用于等下Spring启动之后创建这个bean
现在需要重点研究AnnotationAwareAspectJAutoProxyCreator 这个类干了什么
查看AnnotationAwareAspectJAutoProxyCreator 的继承树
-  AnnotationAwareAspectJAutoProxyCreator 核心需要注册的类也是整个AOP原理的入口 
-  BeanFactoryAware 接口是spring aware接口体系中的一个,实现了该接口的类Spring会把BeanFactory传递给该组件,拿到BeanFactory就可以使用BeanFactory进行组件的注册 
-  SmartInstantiationAwareBeanPostProcessor 核心继承类,他又继承了InstantiationAwareBeanPostProcessor 该类中有2个核心方法 - postProcessBeforeInstantiation 在Spring创建bean之前能够通过这个方法返回一个代理对象来替代需要创建的bean,这次是Spring AOP代理对象的核心,如果此方法返回了对象,Spring会直接拿加强过的bean作为组件注册,不会再注册我们自己写的bean信息
 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } }
-  BeanPostProcessor bean的后置处理器 spring功能扩展的核心,在bean初始化前后可以对bean做一些增强 如@Autowire注解就有对应了AutowiredAnnotationBeanPostProcessor来进行对bean的属性赋值的增加 
以上分析AnnotationAwareAspectJAutoProxyCreator 的主要功能,下面进入Spring自动注册流程的分析
查看主类的run方法
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
- 获取SpringApplicationRunListener 并在合适的地方触发这些listener
- 在准备创建IOC环境之前 listener start方法
- 在准备ConfigurableEnviroment 之前调用listeners.environmentPrepared
- 准备环境
- 根据项目类型创建不同的上下文 如MVC上下文还是WEB-FLUX上下文
- 准备上下文之前 listeners.contextPrepared(context)
- 准备上下文
- 准备上下文之后 listeners.contextLoaded(context)
- 刷新上下文 refreshContext
- afterRefresh 方法
- listener.started
- 执行ApplicationRunner和 CommandRunner
核心refresh方法
	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);
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				// Initialize message source for this context.
				initMessageSource();
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
				// Initialize other special beans in specific context subclasses.
				onRefresh();
				// Check for listener beans and register them.
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
				// Last step: publish corresponding event.
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();
				// Reset 'active' flag.
				cancelRefresh(ex);
				// Propagate exception to caller.
				throw ex;
			}
			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
-  刷新准备 
-  获取beanFactory 
-  准备beanFactory 
-  执行beanFactory的postProcessor 
-  注册BeanPostProcessor AOP org.springframework.aop.config.internalAutoProxyCreator核心逻辑在此处体现 包括了动态道理底层 - 先注册带优先级和排序priorityOrderedPostProcessors
- 在注册带排序的orderedPostProcessors
- 最后注册普通的PostProccessorts
 
-  其中跟AOP相关的核心BeanPostProcessor的创建就在这里  -  调用底层beanfactory的getBean 方法 底层有调用了doGetBean -> getSingleton获取单实例的bean protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
-  底层先从Spring的一级缓存 singletonObjects 中找有没有这个bean,第一次获取肯定没有 
-  然后判断从一级缓存拿到的bean是不是为空 并且正在创建 如果正在创建尝试从二级缓存中拿 (此处逻辑是Spring 处理循环依赖的核心) - 如果二级缓存 singletonObjects 也没有,再判断是否是需要早起暴露的bean
- 如果是加锁从三级缓存singletonFactories 拿到objectFactory然后调用objectFactory的getObject 方法生成一个bean
- 然后 移动到二级缓存earlySingletonObjects 并将三级缓存singletonFactories 从删除这个引用
 
-  第一次创建AOP的beanPostProcessor其实没有走上面逻辑,getSingleton直接返回null 
   
-  
-  下面开始创建bean,创建之前先标记当前bean被创建了 if (!typeCheckOnly) { markBeanAsCreated(beanName); }
-  然后获取bean的定义信息 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args);
-  然后获取是否存在依赖其他bean 如果有遍历获取 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } }
-  判断是否是需要创建单例的bean如果是调用createBean创建 @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 省略 try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. AOP的核心在于这里 Spring在bean创建之前调用BeanPostProcessor的postBeforeInstantiation方法让BeanPostProcessor尝试自己返回一个代理对象的bean 还不是自己去创建 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { // 如果代理对象返回了bean 直接返回 没有就继续调用doCreateBean方法进行创建 return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
-  其实在我们创建AOP的BeanPostProcessor中还没有任何BeanPostProcessor可以拦截我们创建代理对象.但是这里的逻辑是我们自定义切面的核心 我们自己的bean会在创建以前被AOP的beanPostProcessor通过pointCut逻辑进行拦截,进行对我们的bean进行加强,稍后详细分析 
-  因为没有任何BeanPostProcessor 返回了代理对象的bean,继续进入doCreateBean if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); }
-  createBeanInstance创建bean实例 - 进去判断是否需要自动注入到参的构造器
- 如果没有特殊处理走无参构造器
- return instantiateBean(beanName, mbd);
 
-  instantiateBean底层就调用了Spring的BeanUtils工具类调用反射创建无参构造器 
-  执行applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 
-  属性赋值populateBean(beanName, mbd, instanceWrapper); 如果内部需要注入bean再调用getSingleton去创建如果没有创建 
-  执行初始化方法 invokeInitMethods 
-  执行BeanPostProcessor的后置处理器 postProcessAfterInitialization方法 
-  将beanPostProccessor加入到beanfactory 
-  此时org.springframework.aop.config.internalAutoProxyCreator已经注册到了容器中 
@Aspect
@Component
public class AopPointCut {
    @Pointcut("execution(public * com.corn.turorial.spring.aop.AopTestService.*(..))")
    private void pointCut() {
    }
    @Before(value = "pointCut()")
    public void before() {
        System.out.println("前置通知...");
    }
    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("环绕前通知..");
        Object returnData = null;
//        returnData = point.proceed();
        try {
            returnData = point.proceed();
        } catch (Throwable throwable) {
            System.out.println("方法出现了异常!");
        }
        System.out.println("环绕后通知..");
        return returnData;
    }
    @After(value = "pointCut()")
    public void after() {
        System.out.println("后置通知...");
    }
    @AfterReturning(value = "pointCut()")
    public void afterReturning() {
        System.out.println("返回通知...");
    }
    @AfterThrowing(value = "pointCut()")
    public void afterThrowing() {
        System.out.println("异常通知...");
    }
}
@Component
public class AopTestService {
    public void testAop() {
//        int a = 1/0;
        System.out.println(" invoke com.corn.turorial.spring.aop.AopTestService.testAop !");
    }
}
-  然后我们在研究这个beanPostProcessor是如何增加我们的类 
-  直接定位到refresh方法的finishBeanFactoryInitialization(beanFactory); 初始化剩下的bean public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; 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); } } } for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
-  此时我们关心我们自己的bean 判断是不是抽象的 是不是单例 是不是懒加载 然后判断是不是一个以&开头的工厂bean我们不是走getBean逻辑  
-  本质上跟我们直接创建beanPostProcessor类似 -  尝试从一级缓存singletonObjects中拿 
-  没有判断是否是单例的 是的话调用getSingleton的重载方法 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)  
-  进入查看createBean 类似一样的步骤 最核心跟普通bean不一样是resolveBeforeInstantiation方法 此时会进入AOP的 beanPostProcessor返回一个加强的bean  
-  判断是不是InstantiationAwareBeanPostProcessor protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
-  找到AOP增加的beanPostProcessor  
-  进入postProcessBeforeInstantiation方法 - 判断当前bean是否在advisedBean中是否需要增强
- 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean或者是否是切面
- 是否需要跳过 
      - 获取候选增强器 切面的增强通知方法 【List candidateAdvisors】
- 每个封装的通知方法增强器是 InstantiationModelAwarePointcutAdvisor
- 判断每个增强器是否是 AspectJPointcutAdvisor
 
 
-  进入postProcessAfterInitialization方法 - wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
- 获取当前bean的所有增强器 specificInterceptors 
      - 获取候选的所有增强器 (根据切入点获取需要切入方法)
- 获取bean能使用的增强器
- 增强器排序
 
- 保存当前bean的adviseBeans
- 如果当前bean需要增强,创建当前bean的代理对象 
      - 获取所有增强器
- 保存到proxyFactory中
- 创建代理对象 Spring 底层有两种代理模式JDK JdkDynamicAopProxy 和 CGLIB ObjenesisCglibAopProxy
- 给容器中返回当前组件使用cglib增强代理对象
- 以后容器中获取的就是这个组件的代理对象,执行目标方法,代理对象就会执行通知方法
 
 
 
 目标方法执行 - 容器中保存了组件的代理对象,对象保存了详细信息(增强器,目标对象等)
- CglibAopProxy.intercept();拦截方法执行
- 根据ProxyFactory对象获取将要执行的目标方法拦截器
- List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 遍历所有增强器转换为Interceptor registry.getInterceptors(advisor);
- 将增强器转为List
- 如果没有拦截器直接执行目标方法
- 如果有拦截器 将目标对象和目标方法传入 CglibMethodInvocation对象 调用 并调用 Object retVal = mi.proceed();
- 拦截器链的触发过程 
    - 如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数组大小-1相等(说明已经执行到了最后一个拦截器) 执行目标方法
- 链式获取每一个拦截器,执行拦截器的invoke方法,每个拦截器等待下一个拦截器执行完毕返回 递归调用,保证通知方法与目标方法的调用顺序
 
 总结- @EnableAspectJAutoProxy 开启AOP
- @EnableAspectJAutoProxy 向容器中注册一个组AnnotationAwareAspectJAutoProxyCreator
- AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
- 容器创建过程 
    - registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
- finishBeanFactoryInitialization 初始化剩下的单实例bean 
      - 创建业务逻辑和切面组件
- AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
- 组件创建完成之后,判断组件是否需要增强 
        - 是切面通知方法,包装成增强器Advisor给业务逻辑组件创建一个代理对象cglib
 
 
 
- 调用目标方法 
    - 代理对象执行目标方法
- CglibAopProxy.intercept(); 
      - 得到目标方法的拦截器链 由增强器包装成拦截器MethodInterceptor
- 利用拦截器的链式机制,依次进入每个拦截器进行执行
- 正常执行 前置通知->目标方法->后置通知->返回通知
- 异常执行: 前置通知 -> 目标方法 -> 后置通知 -> 异常通知
 
 
 
-  










