不知道还记得IoC中创建Bean后,在DI过程中AbstractAutowireCapableBeanFactory#createBean;
地址:https://blog.csdn.net/java_yes/article/details/97615484
其中有一段代码,用来返回代理对象的,既然AOP和代理有关,那猜测一下,这段代码也和AOP有关。
try {
// 给BeanPostProcessors后处理器一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果还没被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 确定bean的的类型(class类)
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 执行后置处理器在初始化前
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 执行后置处理器在初始化后
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
先说applyBeanPostProcessorsBeforeInstantiation
/** BeanPostProcessors to apply in createBean */
private final List beanPostProcessors = new ArrayList<>();
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class> beanClass, String beanName) {
// 获取createBean 过程中所有 BeanPostProcessors(bean后置处理器)
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 判断 实例
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 重点 :获取 代理类 实际返回的
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
看下postProcessBeforeInstantiation
postProcessBeforeInstantiation 是 AbstractAutoProxyCreator类的
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
// 获取缓存中的key,也就是BeanClass
Object cacheKey = getCacheKey(beanClass, beanName);
// 判断 目标集合targetSourcedBeans 是否包含当前 Bean,不包含的话
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 判断当前bean 是否存在 advisedBeans中
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 重点:isInfrastructureClass 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)。
// 重点:shouldSkip 判断是否需要跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
// 获取封装当前bean的TargetSource对象
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
// 如果不存在 == null,则直接退出当前方法。
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 重点:否则从TargetSource 中获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
ok 这里有三个重点:
isInfrastructureClass
判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)。shouldSkip
判断是否需要跳过Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
isInfrastructureClass 有 两个实现类:
AnnotationAwareAspectJAutoProxyCreator
AbstractAutoProxyCreator
看下AbstractAutoProxyCreator
类关系继承图
类AbstractAutoProxyCreator
最终的子类是 AnnotationAwareAspectJAutoProxyCreator
通过打断点可知,先走的是子类的AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
@Override
protected boolean isInfrastructureClass(Class> beanClass) {
// 调用父类AbstractAutoProxyCreator 的 isInfrastructureClass
return (super.isInfrastructureClass(beanClass) |
// 判断aspectJAdvisorFactory 是否 为null 对象,判断是否使用@Aspect注解
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
@Override
public boolean isAspect(Class> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
// 这个类必须有@Aspect这个注解,并且没有被AspectJ编译过,
// 判断的条件就是这个类中所有的属性,不能是“ajc$”开头。
// 通过这两个判断我们找到了切面类,将这个beanName放入到了aspectNames中缓存。
private boolean hasAspectAnnotation(Class> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
很明显isAspect
是判断当前类是否被标注为@Aspect
,但通过代码深入我们看到所有校验条件为:
我们再看父类AbstractAutoProxyCreator
protected boolean isInfrastructureClass(Class> beanClass) {
// 如果beanClass是Advice、Advisor、AopInfrastructureBean是他们的中的一种,
// 那么就是基础设施类,不能被代理。
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
说过了上面isInfrastructureClass(beanClass)
,再说下shouldSkip
@Override
protected boolean shouldSkip(Class> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
// 获取所有的候选 Advisor
List candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
// 判断BeanName是否相同
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
// 父类返回默认false(改方法不进行深入)
return super.shouldSkip(beanClass, beanName);
}
这里的重点就是
同样有两个实现类:
@Override
protected List findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 父类 :在当前bean工厂中查找所有符合条件的 advisor bean,忽略factorybean并排除当前正在创建的bean。
List advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 将@Aspect注解类, 解析成Advisor
if (this.aspectJAdvisorsBuilder != null) {
// 判断beanName
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
protected List findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
// 重点:获取Advisor集合
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List 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!
// 根据beanNamesForTypeIncludingAncestors 获取所有Advisor类型的Bean的名称
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
// 获取到beanName为空的话,直接返回空 LinkedList
if (advisorNames.length == 0) {
return new LinkedList<>();
}
List advisors = new LinkedList<>();
for (String name : advisorNames) {
// 默认返回true
if (isEligibleBean(name)) {
// 判断当前bean是否在创建中
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 根据beanName 获取 bean,添加到advisors中。
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
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;
}
// 在当前bean工厂中查找带aspectj注释的方面bean,并返回所有Advisor
public List buildAspectJAdvisors() {
List aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
// 获取所有给定类型的bean(传入的是Object,也就是所有类型的)
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历所有beanName
for (String beanName : beanNames) {
// isEligibleBean 默认返回 true
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 根据beanName 获取bean
Class> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 判断当前类是否被标注 @Aspect 注解
if (this.advisorFactory.isAspect(beanType)) {
// 将该bean加入到aspectNames列表中
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List 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.
// 判断bean是否是单例
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 advisors = new LinkedList<>();
// 遍历所有被标注@Aspect注解的beanName
for (String aspectName : aspectNames) {
// 获取所有List
List cachedAdvisors = this.advisorsCache.get(aspectName);
// 获取cache中aspectName对应List不为null
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
// 否则根据beanName 获取 MetadataAwareAspectInstanceFactory对象,将其加入
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false)
获取到容器中的所有的Bean
的名称,放入列表,遍历列表,根据每个Bean
的名称,获取对应的Bean
的类型,根据beanType
判断是否是切面this.advisorFactory.isAspect(beanType)
,这里的isAspect
就是上面说过的。
最后buildAspectJAdvisors
方法创建了MetadataAwareAspectInstanceFactory
,通过该对象获取对应的advisor
,并将其加入到List
中。
this.advisorFactory.getAdvisors(factory)
@Override
public List getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取Aspect标注的类 class对象
Class> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 获取Aspect()标注的类名
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 advisors = new LinkedList<>();
//重点 : 遍历该类所有方法,根据方法判断是否能获取到对应 pointCut,如果有,则生成 advisor 对象
for (Method method : getAdvisorMethods(aspectClass)) {
// 重点:获取Advisor对象
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
// 如果advisors列表为空,且获取
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// 获取 @DeclareParents 注解修饰的属性(并不常用)
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
先看getAdvisorMethods方法
private List getAdvisorMethods(Class> aspectClass) {
final List methods = new LinkedList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
// 判断当前方法是否使用了@Pointcut注解
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
});
// 排序
methods.sort(METHOD_COMPARATOR);
return methods;
}
再看getAdvisor
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 重点:根据候选方法名,来获取对应的 pointCut
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 如果能获取到 pointCut,则将切点表达式 expressionPointcut、
// 重点 :当前对象ReflectiveAspectJAdvisorFactory、 方法名等包装成 advisor 对象
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
getPointcut
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class> candidateAspectClass) {
// 获取 aspectJAnnotation 对象
AspectJAnnotation> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
findAspectJAnnotationOnMethod
该方法找到并返回第一个被@AspectJ 标注的类
@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation> findAspectJAnnotationOnMethod(Method method) {
// 定义class对象数组,如果方法中有以下注解中任何一种,则返回该类
Class>[] classesToLookFor = new Class>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class> c : classesToLookFor) {
AspectJAnnotation> foundAnnotation = findAnnotation(method, (Class) c);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
instantiateAdvice
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
getAdvice
为给定的@AspectJ通知方法构建一个SpringAOP通知。
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 获取工厂中标注@AspectJ的类
Class> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 类校验
validate(candidateAspectClass);
// 获取 aspectJAnnotation 对象
AspectJAnnotation> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
// 再次判断是不是一个被@AspectJ标注的类
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
// 判断日志
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
// 判断通知类型
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
说了这么多,终于把在applyBeanPostProcessorsBeforeInstantiation
中做的事说完了。
List
与缓存中的advisor.getName
进行比较,判断是不是一个Bean,来确定是否返回