「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」 前言 本篇文章会介绍Spring中AOP的代理Bean的创建过程,对于AOP大家或多或少的都有些了解,无非就是创建代理,横切逻辑插入到目标方法执行的前后,原理就是如此,但是在实现上却十分复杂,下面一起看下 首先介绍下AOP的相关概念
- Aspect :切面,切入系统的一个切面,比如事务管理是一个切面
- Join point :连接点,也就是可以进行横向切入的位置
- Advice :通知,切面在某个连接点执行的操作(分为: Before advice,After returning advice, After throwing advice,After (finally) advice,Around advice )
- Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方
之前在Bean的加载流程提到过,在createBean的过程中会调用一次resolveBeforeInstantiation()方法来返回一个代理的Bean,AOP的核心是 AnnotationAwareAspectJAutoProxyCreator类,如下图所示:
上图可知又是BeanPostProcessor的实现类 具体的实现方法是在AbstractAutoProxyCreator中,也就是Bean加载过程中要经过 AbstractAutoProxyCreator.postProcessBeforeInstantiation(),postProcessAfterInitialization(),两个方法。
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
//省略
}
return null;
}
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//beanName;
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//todo earalyProxy 是用来缓存提前暴露对象的缓存key
if (!this.earlyProxyReferences.contains(cacheKey)) {
//创建代理Bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
本文主要从postProcessAfterInitialization开始描述,重点关注入口wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//这里表示已经处理过
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//这里表示无需增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//@1.1 给定的bean类是否Advice,Pointcut,Advisor,AopInfrastructureBean等这些类不需要被代理,
//@1.2 或是指定的bean不需要被代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//@1.3 获取增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//要是获取到了增强则需要针对增强进行代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//@1.4 这里创建代理
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;
}
上述代码可知创建一个代理对象大致流程为:
- 判断是否是特殊的Bean的类型,以及是否跳过.
- 获取增强器
- 创建代理Bean 主要分为三个过程,看着很简单的过程但是这三个流程是十分十分十分十分复杂的,下边开始一点一点的分析。
@1.1 isInfrastructureClass
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
return retVal;
}
如果是Advice,Pointcut,Advisor,AopInfrastructureBean类型的bean就跳过
@1.2 shouldSkip()
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// @1.2.1 获取所有的的Advisor增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
@1.2.1 findCandidateAdvisors() 获取增强器
@Override
protected List<Advisor> findCandidateAdvisors() {
//@1.2.1.1这一步其实就是获取Spring配置文件中定义的Advisor
//或者被@Bean注解标识的Advisor例如BeanFactoryCacheOperationSourceAdvisor
//和事务相关的BeanFactoryTransactionAttributeSourceAdvisor都是这一步获取到
List<Advisor> advisors = super.findCandidateAdvisors();
//@1.2.1.2 解析 @Aspect 注解,并构建通知器合并到List
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
@1.2.1.1 findCandidateAdvisors()
@Override
protected List<Advisor> findCandidateAdvisors() {
//@1.2.1.1这一步其实就是获取Spring配置文件中定义的Advisor
//或者被@Bean注解标识的Advisor例如BeanFactoryCacheOperationSourceAdvisor
//和事务相关的BeanFactoryTransactionAttributeSourceAdvisor都是这一步获取到
List<Advisor> advisors = super.findCandidateAdvisors();
//@1.2.1.2 解析 @Aspect 注解,并构建通知器合并到List
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
从这个类中大致能猜出findCandidateAdvisors()是干嘛的,就是从BeanFactory中获取Advisor类型的Bean,下边具体分下这个方法
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
//获取所有的beanName IOC定义的所有的Beanname
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//循环找出增强
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
//获取对应的bean类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
//存入到list中
aspectNames.add(beanName);
//封装切面元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//@1.2.1.2.1 获取增强器
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
//判断是否是单例
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
//.........
} } }
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<>();
for (String aspectName : aspectNames) {
//这里获取单例的Advisor
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;
}
上边代码就是从容器中获取增强类的逻辑大致流程就是
- 判断是否有缓存的advisorNames,如果没有从容器中获取所有ClassType为Advisor的BeanName
- 遍历advisorNames并获取到对应Bean 接着继续分析buildAspectJAdvisor() 获取@Aspect注解标识的Advisor
@1.2.1.2 buildAspectJAdvisor()
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
//获取所有的beanName IOC定义的所有的Beanname
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//循环找出增强
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
//获取对应的bean类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
//存入到list中
aspectNames.add(beanName);
//封装切面元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//@1.2.1.2.1 获取增强器
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
//判断是否是单例
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
//.........
} } }
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<>();
for (String aspectName : aspectNames) {
//这里获取单例的Advisor
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;
}
总结下大概逻辑
- 从IOC容器中获取所有的BeanName
- 遍历BeanName数组,获取对应Bean的classType
- 判断当前Class是否被@Aespect注解标识,如果不是则跳过
- 调用getAdvisors()获取增强
- return 最后,源码研究得有耐心,加油!