一、方法入口
上一节中,Spring会创建两个工厂来完成获取增强方法的功能:
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//获取增强方法
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);
}
ReflectiveAspectJAdvisorFactory.getAdvisors:
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取标注有@Aspect注解的类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//切面名称(beanName)
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校验,主要是对@Aspect注解信息的校验
validate(aspectClass);
// 将MetadataAwareAspectInstanceFactory封装起来,对创建的增强器进行缓存,避免多次实例化
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<Advisor>();
//获取类中所有的增强方法(排除带有@Pointcut注解的方法)
for (Method method : getAdvisorMethods(aspectClass)) {
//创建增强器
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// 如果增强器不为空,并且配置了增强延迟初始化,则需要在头部加入同步实例化增强器
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// 获取DeclareParents注解,并创建增强器
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
方法中首先完成普通增强器的获取,然后完成对延迟初始化增强的支持,最后是对@DeclareParents注解的支持
二、获取普通增强器
获取普通增强器是通过getAdvisor实现,包括对切点的注解的获取以及根据注解信息生成增强器:
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//验证@Aspect注解
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取切点信息
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//根据切点信息,生成增强器
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidate