- 前言
- 第一部分 核心实现
- 第 1 章 Spring 整体架构和环境搭建
- 第 2 章 容器的基本实现
- 第 3 章 默认标签的解析
- 第 4 章 自定义标签的解析
- 第 5 章 bean 的加载
- 第 6 章 容器的功能扩展
- 第 7 章 AOP
- 第二部分 企业应用
- 第 8 章 数据库连接 JDBC
- 第 9 章 整合 MyBatis
- 第 10 章 事务
- 第 11 章 SpringMVC
- 第 12 章 远程服务
- 第 13 章 Spring 消息
7.3 创建 AOP 代理
上文中讲解了通过自定义配置完成了对 AnnotationAwareAspectJAutoProxyCreator 类型的自动注册,那么这个类到底做了什么工作来完成 AOP 的操作呢?首先我们看看 Annotation AwareAspectJAutoProxyCreator 类的层次结构,如图 7-1 所示。
图 7-1 AnnotationAwareAspectJAutoProxyCreator 类的层次结构图
在类的层级中,我们看到 AnnotationAwareAspectJAutoProxyCreator 实现了 BeanPostProcessor 接口,而实现 BeanPostProcessor 后,当 Spring 加载这个 Bean 时会在实例化前调用其 postProcess AfterInitialization 方法,而我们对于 AOP 逻辑的分析也由此开始。
在父类 AbstractAutoProxyCreator 的 postProcessAfterInitialization 中代码如下:
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
//根据给定的 bean 的 class 和 name 构建出个 key,格式:beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//如果它适合被代理,则需要封装指定 bean。
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经 处理过
if (this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//无需增强
if (this.nonAdvisedBeans.contains(cacheKey)) {
return bean;
}
//给定的 bean 类是否代表一个基础设施类,基础设施类不应代理,或者配置了指定 bean 不需要自动代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(),
beanName)) {
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
//如果存在增强方法则创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(),
beanName, null);
//如果获取到了增强则需要针对增强创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.add(cacheKey);
//创建代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors,
new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
return bean;
}
函数中我们已经看到了代理创建的雏形。当然,真正开始之前还需要经过一些判断,比如是否已经处理过或者是否是需要跳过的 bean,而真正创建代理的代码是从 getAdvicesAnd AdvisorsForBean 开始的。
创建代理主要包含了两个步骤:
(1)获取增强方法或者增强器;
(2)根据获取的增强进行代理。
核心逻辑的时序图如图 7-2 所示。
图 7-2 AbstractAutoProxyCreator 的 postProcessAfterInitialization 函数执行时序图
虽然看似简单,但是每个步骤中都经历了大量复杂的逻辑。首先来看看获取增强方法的实现逻辑。
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName,
TargetSource targetSource) {
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors,
beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
对于指定 bean 的增强方法的获取一定是包含两个步骤的,获取所有的增强以及寻找所有增强中适用于 bean 的增强并应用,那么 findCandidateAdvisors 与 findAdvisorsThatCanApply 便是做了这两件事情。当然,如果无法找到对应的增强器便返回 DO_NOT_PROXY,其中 DO_NOT_PROXY=null。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论