【十】Spring源码分析之AOP----注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator

AOP源码分析主要分为5个篇章:

1. 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator。 就是本篇。
2. 扫描容器中的切面,创建Advisor对象

【十一】Spring源码分析之AOP----AnnotationAwareAspectJAutoProxyCreator扫描@Aspect,创建Advisor

3. 目标bean和每个Advisor匹配,找出该bean在被代理的时候需要用到哪些Advisor

【十二】Spring源码分析之AOP----匹配出作用于被代理类Advisor

4. 创建代理对象

【十三】Spring源码分析之AOP----生成代理对象

5. 被代理类的方法一次调用流程。

【十四】Spring源码分析之AOP----JdkDynamicAopProxy代理对象invoke调用

这一篇主要是讲 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator

一.注册AnnotationAwareAspectJAutoProxyCreator

1.1AopAutoConfiguration类

SpringBoot启动时

ConfigurationClassProceesor类加载、解析、注册配置类的时候会加载注册spring-boot-autoconfigure-1.5.8RELEASE.jar包下META-INF/spring.factory文件中的允许自动配置的类的时候,即是该标注下的所有类

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

则会加载注册AopAutoConfiguration类,并且会加载注册AopAutoConfiguration配置类中的配置类JdkDynamicAutoProxyConfiguration,而JdkDynamicAutoProxyConfiguration在处理@Import的时候会实例化AspectJAutoProxyRegistrar

org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

 AopAutoConfiguration源码

package org.springframework.boot.autoconfigure.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.Advice;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = false)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
	public static class JdkDynamicAutoProxyConfiguration {

	}

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = true)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
	public static class CglibAutoProxyConfiguration {

	}

}

该类做了2件事

1.@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })

AopAutoConfiguration创建前需要有EnableAspectJAutoProxy.class, Aspect.class, Advice.class。

2.AopAutoConfiguration该配置类会根据@EnableAspectJAutoProxy(proxyTargetClass = true)是为true还是为false来生成不同的自动代理配置类,JdkDynamicAutoProxyConfiguration 或CglibAutoProxyConfiguration 。默认生成的自动代理类是JdkDynamicAutoProxyConfiguration

1.2EnableAspectJAutoProxy注解

源码:

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

可以看到该注解@Import(AspectJAutoProxyRegistrar.class),所以在解析JdkDynamicAutoProxyConfiguration的时候处理@Import注解就会把AspectJautoProxyRegistrar实例化了。

1.3 AspectJAutoProxyRegistrar类

源码:

package org.springframework.context.annotation;

import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

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

        //注册 AnnotationAwareAspectJAutoProxyCreator
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);

        //将 aop 代理方式相关的变量设置到 AopConfigUtils,创建代理类时会读取变量
		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
		}
	}

}

做了2件事:

1.AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)方法注册 AnnotationAwareAspectJAutoProxyCreator

2.将 aop 代理方式相关(proxyTargetClassexposeProxy)的设置到BeanFactory已注册的BeanDefinition中,创建代理类时会读取变量

 先说一下AspectJAutoProxyRegistrar类的这个方法registerBeanDefinitions会在什么时候被调用,即是入口,从方法调用栈中可以看到:

注册JdkDynamicAutoProxyConfiguration的时候,会调用AspectJAutoProxyRegistrar类的registerBeanDefinitions方法去注册AnnotationAwareAspectJAutoProxyCreator

1.3.1 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary

源码:

	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {

        //这里注册AnnotationAwareAspectJAutoProxyCreator类
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

做了1件事:

这里注册的AutoProxyCreator是AnnotationAwareAspectJAutoProxyCreator类,该方法跟进去调用的是registerOrEscalateApcAsRequired方法

1.3.1.1 registerOrEscalateApcAsRequired方法

源码:

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

做了2件事:

1.autoProxyCreator类是否已注册到BeanFactory中,如果没有,则注册入参传进来的autoProxyCreator类。

2.如果已经注册了,就拿来出看比较一下是否跟入参传进来的autoProxyCreator类的名字一样,不一样并且已有的那个autoProxyCreator优先级低于入参才传进来的这个autoProxyCreator,那就升级成入参才传进来这个。

二、实例化AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator看一下类图

它继承了BeanPostProcessor接口,在AbstractApplicationContest的refresh方法中调用registerBeanPostProcessors(beanFactory)方法时,会把所有继承了BeanPostProcessor接口的类提前实例化。

所以,实例化AnnotationAwareAspectJAutoProxyCreator的入口是:

(方法栈)

至于这里创建的详细过程请看另一篇博客专门讲getBean方法的:

【五】Spring源码分析之实例化Bean----DefaultListableBeanFactory的preInstantiateSingletons方法

该博客的第四部分就是将getBean方法的

三、初始化AnnotationAwareAspectJAutoProxyCreator

实例化AnnotationAwareAspectJAutoProxyCreator后,会调用该对象的初始化方法

初始化方法调用栈,初始化入口:

可以看到初始化AnnotationAwareAspectJAutoProxyCreator对象的入口是AbstractAutoWireCapableBeanFactory类的InitializeBean方法,关于该方法另外有一篇博客中有提到过

【七】Spring源码分析之实例化Bean----AbstractAutowireCapableBeanFactory的createBean方法

该博客的3.5就是讲InitializeBean方法

3.1首先是AbstractAutowireCapableBeanFactory类的invokeAwareMethods方法

源码:

private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

做了1件事:

发现AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口,则调用AnnotationAwareAspectJAutoProxyCreator类的setBeanFactory方法。

3.1.1 AnnotationAwareAspectJAutoProxyCreator类的setBeanFactory方法

源码:

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		super.setBeanFactory(beanFactory);
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalArgumentException(
					"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
		initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
	}

做了2件事:

1.把beanFactory设置到AnnotationAwareAspectJAutoProxyCreator中

2.给AnnotationAwareAspectJAutoProxyCreator中的成员(aspectJAdvisorFactory、aspectJAdvisorsBuilder、advisorRetrievalHelper)赋值

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值