- findCandidateAdvisors寻找通知器
-
- AbstractAdvisorAutoProxyCreator的findCandidateAdvisors
-
- BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans
- BeanFactoryAspectJAdvisorsBuilderd的buildAspectJAdvisors(重点)
-
- ReflectiveAspectJAdvisorFactory的getAdvisors
-
- getAdvisorMethods获取Pointcut注解的方法
findCandidateAdvisors寻找通知器
上篇讲到shouldSkip
的方法,里面其实挺复杂,主要就是findCandidateAdvisors
方法。
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
AbstractAdvisorAutoProxyCreator的findCandidateAdvisors
首先会调用BeanFactoryAdvisorRetrievalHelper
来寻找是否有Advisor
的bean
定义。
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans
其实就是寻找所有Advisor.class
的bean
名字,如果存在就放入缓存,并进行创建,然后返回。
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] 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 ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
...
throw ex;
}
}
}
}
return advisors;
}
BeanFactoryAspectJAdvisorsBuilderd的buildAspectJAdvisors(重点)
这里就是复杂的地方啦,其实他做的就是寻找Aspect
注解的切面对象,然后解析他的方法,通过注解来生成对应的通知器Advisor
。
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;//获取切面名字列表
//只找一次
if (aspectNames == null) {
synchronized (this) {
//双重检查
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();//通知集合
aspectNames = new ArrayList<>();//切面名字列表
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(//寻找所有object类型的bean定义名字
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
//遍历获取有Aspect注解的加入到aspectNames列表
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);//获取类型,如果不存在,可能已经被代理过了
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
//是否有Aspect注解的
aspectNames.add(beanName);
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);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
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;
}
ReflectiveAspectJAdvisorFactory的getAdvisors
首先获取切面类型,然后获取除Pointcut
注解的所有方法,根据方法注解来创建Advisor
通知器。
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();//获取切面
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);//验证
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
for (Method method : getAdvisorMethods(aspectClass)) {
//获取通知器方法
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);//创建Advisor
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.introduction处理
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
getAdvisorMethods获取Pointcut注解的方法
这里会后的所有不包含Pointcut
注解的方法,让然后进行排序,根据这个注解顺序Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
,然后才是普通方法。
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
methods.sort(METHOD_COMPARATOR);
return methods;
}
然后就是关键的getAdvisor
方法了,这个我们后面说吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。