背景
事情的起因是这样的 。中间件这边做了一套缓存sdk框架。其实是对spring mvc那一套做了一些功能封装并且增加了一些属性,支持了自定义过期时间,请求序列化等等操作。再给也无妨同学接入的时候,出现了尴尬的一幕 : 按照说明文档接入了以后(其实就是引入xml,和dependency)。在想要加缓存的地方加上我们自定义的注解。 结果是 : 不起作用。 并没有走缓存,还是去查数据库。因此我们对spring的增强器那块代码做了一个review。增强器整理分为上下2部分。上篇讲述获取增强器的具体流程。下面讲述获取增强器的机制。会在下篇讲述为什么增强器没有拦截成功。
Spring 增强器的获取
增强器获取是在spring容器启动的时候,会遍历每一个拦截的类,并对其的增强器进行加载 。
// org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获取容器中所有的增强器 (其实包含集成Advisor接口的和带有@Aspect注解的两类对象都会得到。
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//查询可以应用到当前对象的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
可以看到,这个是一个抽象类。执行这个代码的主体对象现在一般是这个类
AnnotationAwareAspectJAutoProxyCreator
,主要是因为注解已经非常普遍了。
这个类重写了查找所有增强器的方法findCandidateAdvisors
,如下
//AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
//可以看到这里其实调用的是父类的查询所有实现了Advisor接口的
//增强器
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
//这里把对@Aspect的支持也增加进来
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
另外,可以看到第一步的父类中寻找增强器的代码 ,寻找advisor其实是通过类
BeanFactoryAdvisorRetrievalHelper
来找的
//BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
到此,增强器的获取,可以看到一个大致的轮廓了 。更细节的可以后面慢慢赏析。
网友评论