文章目录
- 说明
- 什么时候起作用
- 主流程
- Aspect 、Advice、Pointcut、Advisor
- 处理Weaving、Joinpoint、Proxy、Target
- createProxy
说明
本文,从代码来解析AOP的一些概念、源码、流程等…
首先需要对spring AOP 的一些概念需要有一些了解…
- Aspect (切面)
- Advice(通知)
- Pointcut(切入点)
- Advisor(增强器、顾问)我比较喜欢称之为增强器,如果注释中存在增强器指的就是这个…
- Target (目标对象)
切面、通知、切入点
简单说,一个切面定义了 切入点
和通知
而 Advisor(顾问、增强器)将切面的里面的 切入点和通知进行了一个包装
什么时候起作用
也就说 我们的AOP 什么时候去使用的?我们知道 当一个Bean注册的时候会对Bean 做一些列操作 ,简单说也就是 相关 BeanPostProcessor
,而我们通过接口分析得知AnnotationAwareAspectJAutoProxyCreator
最终是实现了SmartInstantiationAwareBeanPostProcessor
、InstantiationAwareBeanPostProcessor
也就是说基本是 执行 BeanPostProcessor
的时候去进行处理的,在通过源码了解到 BeanPostProcessor
是贯穿了我们 Bean 的生命周期的,那其实我们想知道这个什么时候起的作用,只需要知道实现的这几个方法什么时候执行的即可
接口
单从结果上看 仅仅只有 AbstractAutoProxyCreator
去实现了这些方法,子类并没有重新和覆盖
SmartInstantiationAwareBeanPostProcessor
- predictBeanType
- determineCandidateConstructors
- getEarlyBeanReference
InstantiationAwareBeanPostProcessor
- postProcessBeforeInstantiation
postProcessAfterInstantiationpostProcessPropertiespostProcessPropertyValues
调用时机可参考 InstantiationAwareBeanPostProcessor
由AbstractAutoProxyCreator
去实现了这些方法
BeanPostProcessor
postProcessBeforeInitialization- postProcessAfterInitialization
调用时机可参考 BeanPostProcessor
由 AbstractAutoProxyCreator
去实现了这些方法
说明
当创建一个 Bean 的时候,也就说只有2个地方可能会返回代理对象,一个是直接返回代理对象,根本不给机会去创建对象,另一个是走完初始化方法调用后返回代理对象
主流程
主流程指的是DBUG线程调用的地方方法~~,也就说每一次的Bean 创建都会走这里…
- refresh();
- finishBeanFactoryInitialization(beanFactory);
- beanFactory.preInstantiateSingletons();
- getBean(beanName);
- doGetBean()
- getSingleton()
- createBean()
resolveBeforeInstantiation
给 BeanPostProcessors 一个 机会 返回 一个代理替换这个目标 Bean 的 实例,简单来说,直接就通过代理返回结果了
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved 可能是 null 、true、false
// null 代表 bean 没有走过 resolveBeforeInstantiation 这个方法
// true 代表 bean 已经走过 resolveBeforeInstantiation 这个方法
// false 代表 bean 不需要走 resolveBeforeInstantiation 这个方法
// 这里是为了一个效率的存在,当如果 这个 BeanDefinition 已经走过一边后,并且返回了 false 后下次就不会继续走了
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 1. 判断是不是 合成 Bean
// 2. 判断有没有 实现了 InstantiationAwareBeanPostProcessor 这个接口的 BeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 执行前置方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 如果不是 null 就代表已经返回对象了,则会去执行后置方法
if (bean != null) {
// 执行后置方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// bean != null 返回 true 代表 bean 已经被创建
// bean != null 返回 false 代表 bean 不需要进行代理..
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
这里可以看到一个细节就是 BeanDefinition. beforeInstantiationResolved 这个属性 是为了缓存结果,简单来说当走完所有的 InstantiationAwareBeanPostProcessors 后如果都是不创建那就会定义为 false,也就是说在 多例
(原型)的情况下这里的代码如果第一次走完后,下次如果是false就会直接返回.
postProcessBeforeInstantiation
Aspect 、Advice、Pointcut、Advisor
这里简单说就是获取增强器,可以通过XML、接口、注解方式进行配置,来让我们一步一步的将他吃透…大致是这些流程…
postProcessBeforeInstantiation
AbstractAutoProxyCreator.postProcessBeforeInstantiation
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 获取 一个用于缓存 key 其实就是 BeanName
Object cacheKey = getCacheKey(beanClass, beanName);
// 判断 targetSourcedBeans 不包含这个 bean
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 判断需要增强的 Bean 是否包含这个 Bean
// advisedBeans 包含所有 切面Bean 和 增强Bean
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//1. 判断是不是 基础类型,也就说判断是不是 实现了这些接口 Advice、Pointcut、Advisor、AopInfrastructureBean、
//2. 还会判断是不是 有没有 @Aspect 注解
// isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AnnotationAwareAspectJAutoProxyCreator,
// 所以执行 AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass()
// 这段逻辑是处理如果是基础类、切面类、原始类 都不会进行代理
if (isInfrastructureClass(beanClass) ||
// 所以执行 AnnotationAwareAspectJAutoProxyCreator.shouldSkip()
// 判断是不是需要跳过,如果返回true则就会将 这个 name 进行缓存
shouldSkip(beanClass, beanName)) {
// 这里其实是将 切面 Bean 的BeanName 缓存起来,代表这个 Bean 不进行 增强操作
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 如果我们有自定义的TargetSource,请在此处创建代理。
// 禁止目标Bean的不必要的默认实例化: TargetSource 将以自定义方式处理目标实例。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// 这个 BeanName 是正常的
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//创建代理对象
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
shouldSkip
isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AbstractAutoProxyCreator,
所以会执行AnnotationAwareAspectJAutoProxyCreator.shouldSkip()
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 找到候选的 增强器,也就是说是切面里面的通知方法
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 循环所有 增强器
for (Advisor advisor : candidateAdvisors) {
//判断我们的增强器是不是 AspectJPointcutAdvisor 这个类型
if (advisor instanceof AspectJPointcutAdvisor &&
// 并且 增强的名称和我们的BeanName 是一致
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
// 这里基本返回 false..
return super.shouldSkip(beanClass, beanName);
}
// 父类的方法
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 判断是不是 原始的实例,也就是说是不需要进行代理的实例
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
// 如果 BeanName 不正常 返回 false
// beanName 的长度不是 bean全限定类名+ ORIGINAL_INSTANCE_SUFFIX(原始后缀),也返回 false
// 也就是说这里基本会返回 false 那什么时候返回 True 呢 当我们的Bean 是全限定类名 + ORIGINAL_INSTANCE_SUFFIX 的时候...
// 这里可以去手动注册一个 这样的Bean,演示DEMO 在下面~~~
if (!StringUtils.hasLength(beanName) || beanName.length() !=
beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
return false;
}
return (beanName.startsWith(beanClass.getName()) &&
beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
}
//-----------------------------DEMO
// @EnableAspectJAutoProxy
// @ComponentScan
// public class IsOriginalInstanceContext {
// public static void main(String[] args) {
// AnnotationConfigApplicationContext value = new AnnotationConfigApplicationContext();
// value.register(IsOriginalInstanceContext.class);
// value.registerBeanDefinition(IsOriginalInstanceBean.class.getName()
// + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX,
// BeanDefinitionBuilder.genericBeanDefinition(IsOriginalInstanceBean.class).getBeanDefinition()
// );
// value.refresh();
// }
// }
//----------------------------
findCandidateAdvisors(获取所有的增强器)
这里也是同理,会调用AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
这里逻辑分为两步
- 调用父类的
findCandidateAdvisors()
方法获取的是 实现了 Advisor 接口的Bean - 获取的是注解 切面里面所有的 Advisor
protected List<Advisor> findCandidateAdvisors() {
// 获取所有 实现 Advisor 接口的类,这里的代码就不贴了.. 自己可以去看看比如自己转配一个 Bean 去实现这个 Advisor
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;
}
buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
// 因为解析会很消耗性能,所以 Spring 会使用 aspectBeanNames 保存解析结果
List<String> aspectNames = this.aspectBeanNames;
// 如果==null 代表没处理过,因为第二次肯定不为 null,在 进入这个条件后,就会创建 ArrayList
if (aspectNames == null) {
// 进行加锁处理,防止多线程情况下一起操作解析
synchronized (this) {
// 二次赋值,防治以及操作过了
aspectNames = this.aspectBeanNames;
//双重非空判断,避免再次解析
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
// 创建切面集合
aspectNames = new ArrayList<>();
// 查找所有的 BeanName 包括父类
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
//排除不合法的ban,由子类定义规则,默认返回true
if (!isEligibleBean(beanName)) {
continue;
}
// 根据Name获取Class类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 判断 是否存在 @Aspect 注解 并且判断 目标类上所有的属性不包含 "ajc$"
if (this.advisorFactory.isAspect(beanType)) {
// 将 切面的 BeanName 放入到集合中
aspectNames.add(beanName);
// 包装成 AspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
//检查 @Aspect 注解的value值,验证生成的增强是否是单例
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 创建一个工厂..
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 获取标记 Aspect 注解的增强方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
//如果bean是单例,则缓存bean的增强器
if (this.beanFactory.isSingleton(beanName)) {
// 将 切面 BeanName 和 增强器 进行缓存
this.advisorsCache.put(beanName, classAdvisors);
}
// bean非单例,只缓存bean对应的增强器创建工厂
else {
this.aspectFactoryCache.put(beanName, factory);
}
// 将获取的 增强器 放入到集合中
advisors.addAll(classAdvisors);
}
else {
// 切面创建模式非单例,这里的Else 基本不会进来...
// 如果切面是非单例,但是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));
}
}
}
//将已经解析过的切面 Bean 进行缓存
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// 如果是 null 就会直接返回...
if (aspectNames.isEmpty()) {
// 如果是一个空的就返回一个空集合
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
// 循环 切面的Name
for (String aspectName : aspectNames) {
// 根据切面的Name 获取 增强器
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;
}
getAdvisors(获取所有增强器)
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取 切面的 Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 获取 切面的 Name
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<>();
// 获取 切面的所有方法,排除 @Pointcut
for (Method method : getAdvisorMethods(aspectClass)) {
// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
// to getAdvisor(...) to represent the "current position" in the declared methods list.
// However, since Java 7 the "current position" is not valid since the JDK no longer
// returns declared methods in the order in which they are declared in the source code.
// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
// discovered via reflection in order to support reliable advice ordering across JVM launches.
// Specifically, a value of 0 aligns with the default value used in
// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
// 尝试解析每个方法,找到方法对应的切点和通知
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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;
}
getAdvisor(获取单个增强器)
从这里可以看出 Advisor 指的就是 切入点和通知的集合
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// 校验...
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 获取 切入点
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 在创建 InstantiationModelAwarePointcutAdvisorImpl 的时候 里面有一个 instantiateAdvice--> getAdvice 比较重要需要看一下
// 将切入点和通知包装成一个 增强器
return new InstantiationModelAwarePointcutAdvisorImpl(
expressionPointcut, //切入点表达式
candidateAdviceMethod, //通知方法
this,
aspectInstanceFactory, // 切面实例的工厂..
declarationOrderInAspect, //0
aspectName //切面名称
);
}
getPointcut(获取切入点)
获取Pointcut(切入点),需要说明的是这里如果使用的 @Pointcut 定义的切入点… 并没有进行解析,简单说 AspectJExpressionPointcut 的 Pointcut 仅仅是 @Pointcut的方法名…
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 获取方法的(通知)
// Pointcut.class,
// Around.class,
// Before.class,
// After.class,
// AfterReturning.class,
// AfterThrowing.class
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;
}
1
创建InstantiationModelAwarePointcutAdvisorImpl(通知和增强器)
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 精简代码....
// 如果是懒加载
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// 这里不用太关注.
}
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(获取通知)
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//切面类 带有@Aspect注解的类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
// 获取方法的(通知)来确认当前方法是具体的那个类型的通知
// Pointcut.class,
// Around.class,
// Before.class,
// After.class,
// AfterReturning.class,
// AfterThrowing.class
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//再去校验一遍 如果不是切面类 则抛出异常
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("");
}
AbstractAspectJAdvice springAdvice;
// 根据通知类型,创建不同的通知~~
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//如果是前置通知,则直接创建AspectJMethodBeforeAdvice实例
//入参为:通知方法、切点表达式、切面实例
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//如果是后置通知,则直接创建AspectJAfterAdvice实例
//入参为:通知方法、切点表达式、切面实例
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//如果是后置返回通知,则直接创建AspectJAfterReturningAdvice实例
//入参为:通知方法、切点表达式、切面实例
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
//设置后置返回值的参数name
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
//如果是后置异常通知,则直接创建AspectJAfterThrowingAdvice实例
//入参为:通知方法、切点表达式、切面实例
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
//设置后置异常通知 异常类型参数name
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// 切面的名字
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
// 通知注解中的参数名,换而言之就是获取 通知注解中的 argNames 属性
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
//计算argNames和类型的对应关系
springAdvice.calculateArgumentBindings();
return springAdvice;
}
getCustomTargetSource
这个单独领出来说,是这里…想要进入条件比较刻薄
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// customTargetSourceCreators 不为空
// beanFactory 不为空
// bean 存在 spring容器中
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
// Found a matching TargetSource.
if (logger.isTraceEnabled()) {
logger.trace("TargetSourceCreator [" + tsc +
"] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
}
}
// No custom TargetSource found.
return null;
}
说明
整个上面的所有代码都是获取 Aspect 和 Advice 和 Pointcut
- 缓存了 实现了 Advisor 接口 Bean 的name
- 缓存了 @Aspect 注解的 Bean 的name
- 缓存了 切面 Bean 下面的所有 Advisor(Advice、Pointcut)
为什么这么做… 为了效率,因为每一次都会去拦截,每次都会去走一遍,对其数据进行缓存,其实随处可见的细节太多了…
处理Weaving、Joinpoint、Proxy、Target
根据主流程~~ 继续DBUG,也就是说没有直接返回代理对象~~这里的代码就不贴了,直接贴核心代码
- doCreateBean
- initializeBean
- applyBeanPostProcessorsAfterInitialization
分析 postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
// 判断这个对象是否创建成功..
if (bean != null) {
// 获取一个 key ,用于缓存..
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 这里就是去搞代理去了
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary(包装目标类,如果需要的话)
这里的细节点是 可以看到 advisedBeans.put(cacheKye,Boolean.FALSE) 或者ture ,其实为了就是效率…
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 判断 beanName是正常的 并且 targetSourcedBeans 已经存在则会直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//判断 Bean 是不是 不需要增强,如果不需要直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//判断 是不是 切面 这里上面已经分析过了....
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 如果是 切面 放入到集合当中,
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 创建代理对象
// 1. 获取当前Bean 的所有增强器(通知方法)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果不是 null 则会去生成代理对象,否则则标记当前类不需要进行代理.
if (specificInterceptors != DO_NOT_PROXY) {
// 将其放入到集合当中代表已经增强过了...
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 将数据进行缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理对象...
return proxy;
}
// 如果不需要代理则设置为 False 当下次进来的时候会直接返回(细节)
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
getAdvicesAndAdvisorsForBean
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//获取这个类型的所有增强器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 如果是一个空的 则返回 一个空的 数组
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
// 将其转换成数组返回
return advisors.toArray();
}
findEligibleAdvisors(找到合适的增强器)
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;
}
findAdvisorsThatCanApply(找到能够应用的增强器)
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 返回当前Bean能用的增强器
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
findAdvisorsThatCanApply(找到能够应用的增强器)
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
// 如果是空..就直接返回..
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
//存放 合格的 增强器
List<Advisor> eligibleAdvisors = new ArrayList<>();
//循环所有的增强器
for (Advisor candidate : candidateAdvisors) {
//判断类型是不是整个类型的
if (candidate instanceof IntroductionAdvisor
// 去应用..
&& canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 循环所有的增强器
for (Advisor candidate : candidateAdvisors) {
//判断如果是这个类型的就跳过,因为上个循环已经处理过了
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 判断是不是能用的增强器,如果是能用的则添加到集合当中去
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
canApply(能够应用的增强器)
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
// 判断 是不是这个类型的
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
// 判断 是不是这个类型的
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
// 判断切入点表达式是否匹配
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// 它没有切入点,因此我们假设它适用。
return true;
}
}
canApply(能够应用的增强器)
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 这一步会去解析 切入点表达式...
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
// 判断是否是 Proxy 的子类并且 proxyClassCache 存在 这个类
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
// 返回当前类的所实现的所有的接口..
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
// 获取当前类上包括父类的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 循环所有方法
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
getClassFilter(获取切点表达式)
解析切入点表达式…为过滤做准备
public ClassFilter getClassFilter() {
obtainPointcutExpression();
return this;
}
obtainPointcutExpression(获取切入点表达式)
private PointcutExpression obtainPointcutExpression() {
// 如果表达式不存在 抛出异常...
if (getExpression() == null) {
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
// 如果 切入点表达式 是null 去进行解析,因为我们的表达式可能是 通过@Pointcut 的方式
if (this.pointcutExpression == null) {
this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
return this.pointcutExpression;
}
buildPointcutExpression
去解析表达式…
private PointcutExpression buildPointcutExpression(@Nullable ClassLoader classLoader) {
// 初始化基础的Aspect切入点解析器
PointcutParser parser = initializePointcutParser(classLoader);
// 获取切入点参数...
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
for (int i = 0; i < pointcutParameters.length; i++) {
// 将参数和类型包装一下 放入到数组中
pointcutParameters[i] = parser.createPointcutParameter(
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
}
// 这里嵌套了3个方法....而且还异常复杂我都不忍心看...
return parser.parsePointcutExpression(replaceBooleanOperators(resolveExpression()),
this.pointcutDeclarationScope, pointcutParameters);
}
resolveExpression
private String resolveExpression() {
// 获取表达式
String expression = getExpression();
Assert.state(expression != null, "No expression set");
// 返回表达式
return expression;
}
replaceBooleanOperators
private String replaceBooleanOperators(String pcExpr) {
// 将表达式中的 and 替换
String result = StringUtils.replace(pcExpr, " and ", " && ");
// 将表达式中的 or 替换
result = StringUtils.replace(result, " or ", " || ");
// 将表达式中的 not 替换
result = StringUtils.replace(result, " not ", " ! ");
return result;
}
parsePointcutExpression
public PointcutExpression parsePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters)
throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
PointcutExpressionImpl pcExpr = null;
try {
// 这里是对表达式的进行处理,具体的可以自己深究去
Pointcut pc = resolvePointcutExpression(expression, inScope, formalParameters);
// 将表达式具体化,比如我使用的是 @Before("方法()") 这里是去将 "方法()" 转换成具体的 表达式
pc = concretizePointcutExpression(pc, inScope, formalParameters);
// again, because we have now followed any ref'd pcuts
validateAgainstSupportedPrimitives(pc, expression);
// 包装成 对象返回
pcExpr = new PointcutExpressionImpl(pc, expression, formalParameters, getWorld());
} catch (ParserException pEx) {
throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
} catch (ReflectionWorld.ReflectionWorldException rwEx) {
throw new IllegalArgumentException(rwEx.getMessage());
}
return pcExpr;
}
matches(匹配当前类)
public boolean matches(Class<?> targetClass) {
// 这里是去获取 切入点表达式.. 也包括了解析(这里其实在 getClassFilter) 已经解析过了~~
PointcutExpression pointcutExpression = obtainPointcutExpression();
try {
try {
//根据表达式的解析实例,验证此类是否匹配
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
}
catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
}
couldMatchJoinPointsInType(判断当前类是否可以匹配切入点)
这里仅仅是去匹配当前类是否符合规则
public boolean couldMatchJoinPointsInType(Class aClass) {
ResolvedType matchType = world.resolve(aClass.getName());
if (matchType.isMissing() && (world instanceof ReflectionWorld)) {
// Class is a generated class that cannot be 'looked up' via getResource.
// For example a proxy or lambda.
// Use the class itself in this case
matchType = ((ReflectionWorld)world).resolveUsingClass(aClass);
}
ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world);
//根据切入点和 目标类,判断类 package 是否匹配
boolean couldMatch = pointcut.fastMatch(info).maybeTrue();
return couldMatch;
}
说明
上面一大串代码都是为了去进行匹配,当匹配成功的时候才会去创建代理对象
createProxy
创建代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建 代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 将当前类的一些配置进行 复制 ,简单来说就是获取 XML 或者注解配置的属性..
// 这里可以参考一下:
proxyFactory.copyFrom(this);
// 判断是否是通过接口 默认是 False
if (!proxyFactory.isProxyTargetClass()) {
//根据最开始@EnableAspectJAutoProxy注解中的proxyTargetClass参数判断是否应该使用cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
//标识 使用cglib动态代理
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 获取到增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 放入到 代理工厂
proxyFactory.addAdvisors(advisors);
// 设置 目标 对象
proxyFactory.setTargetSource(targetSource);
// 留个子类去实现的一个方法,也就是说我们可以通过重写这个方法进行定制
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
getProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
// createAopProxy() 获取AOP 工厂判断 CGlib还是JDK
return createAopProxy().getProxy(classLoader);
}
createAopProxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 获取到 AOP 代理工厂
// 然后判断 是 Cglib 还是JDK
return getAopProxyFactory().createAopProxy(this);
}
createAopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!IN_NATIVE_IMAGE &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// optimize 默认是 false
// ProxyTargetClass 默认是 false
// hasNoUserSuppliedProxyInterfaces 被代理的类没有实现接口
// 获取目标 Class
Class<?> targetClass = config.getTargetClass();
// 判断当前类是不是接口
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
getProxy
取决于 createAopProxy
返回的是 CGlib 还是JDK 代理