本文主要是对于他人文章的整理,最后给出了参考链接。具体内容根据本人的理解,有所取舍。后续对于AOP有更深入的理解,再不断进行更新
AOP依赖于ioc容器进行管理。

开启AOP自动代理及触发时机
如果让Spring支持注解模式的AOP,那么需要在启动类上添加@EnableAspectJAutoProxy注解,它的作用是让ioc容器中所有的advisor来匹配方法。注解的定义如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
其中比较重要的注解是@Inport,它将AspectJAutoProxyRegistrar注入到了ioc容器中。源码定义如下:
// 实现了ImportBeanDefinitionRegistrar接口
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册registerAspectJAnnotationAutoProxyCreator的BeanDefinition
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
// 根据@EnableAspectJAutoProxy 注解的proxyTargetClass和exposeProxy属性值,将属性值注入到
// registerAspectJAnnotationAutoProxyCreator的BeanDefinition中
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AspectJAutoProxyRegistrar主要就是将registerAspectJAnnotationAutoProxyCreator的BeanDefinition注册到ioc容器中。
registerAspectJAnnotationAutoProxyCreator的类继承图如下所示:
AspectJAnnotationAutoProxyCreator其实就是一个BeanPostProcessor!
Spring Bean 创建的过程,在执行完创建实例对象createBeanInstance和属性装配populateBean之后,我们才算得到一个真正的实现类。在initializeBean中,IoC容器会处理Bean初始化之后的各种回调事件,然后返回一个最终的bean对象。
其中就包括了BeanPostProcessor的 postProcessBeforeInitialization 回调 和 postProcessAfterInitialization 回调。而AspectJAnnotationAutoProxyCreator恰恰是一个BeanPostProcessor。那就很容易联想到,Spring AOP 就是在这一步,进行代理增强!
代理模式的实现思路是:(接口)+ 真实实现类 + 代理类,先要有真实的实现类,才能生产代理类。
从源码中可以看到,postProcessBeforeInitialization回调和 postProcessAfterInitialization回调是重写了AbstractAutoProxyCreator中的方法。
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
其中postProcessBeforeInitialization方法调用链如下所示:
postProcessAfterInitialization会执行创建代理类的操作,用配置的interceptors 来创建一个代理类。首先,看一下wrapIfNecessary方法的实现:
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 判断是不是基础Bean(Advice、PointCut、Advisor、AopInfrastructureBean),是就直接跳过
// 判断是不是应该跳过,AOP解析直接解析出切面信息,并且将切面信息进行缓存
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 如果定义了advice,则创建代理类
// 返回匹配当前Bean的所有advisor、advice、interceptor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, 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;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
方法的调用链如下所示:
当一个类是合法的可以被代理的类,那么可以使用wrapIfNecessary方法进行进一步的包装,方法的返回值是代理类或者实现类本身。方法的核心逻辑有两步(针对于需要生成代理类的场景):
- 返回匹配当前Bean的所有advisor、advice、interceptor
- 调用createProxy方法实现真正代理类对象的创建
获取Bean匹配的Advisors链
获取匹配当前Bean所有的Advisor分为两步:
- 获取容器中所有的advisor作为候选,即解析ioc容器中所有Aspect类的advice包装成Advisor
- 从候选的Advisor中筛选出匹配当前Bean的Advisors链
其中shouldSkip的实现是AspectJAwareAdvisorAutoProxyCreator的shouldSkip方法,它首先调用findCandidateAdvisors来获取所有的候选Advisors,然后根据传入的beanClass和beanName判断是否是AspectJPointcutAdvisor或AspectJPointcutAdvisor来决定是否跳过。
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
}
而返回匹配当前Bean的所有advisor、advice、interceptor调用的是getAdvicesAndAdvisorsForBean方法,它的源码定义如下:
@Override
@Nullable
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();
}
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;
}
它也是调用了findCandidateAdvisors方法来获取所有候选的Advisors。那么,接下来看一下它如何获取所有的Advisors ,方法源码定义如下:
public List<Advisor> findAdvisorBeans() {
// 获取缓存中所有Advisor对应的beanName
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<>();
// 遍历所有的advisor
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 如果对应的Bean已经被创建,则从BeanFactory中获取指定的Bean,将其添加到advisors这个list中
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.isTraceEnabled()) {
logger.trace("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;
}
}
}
}
// 返回所有已创建的Advisors
return advisors;
}
而获取通过@Aspect注解的Advisor,真正调用的是BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法,源码定义如下:
// 在BeanFactory中寻找被@Aspect注解的Bean,在每个Aspect类的advice方法创建一个Spring Advisor,然后返回Advisors链
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
// 第一次实例化singleton bean时会触发解析切面,解析后aspectNames被缓存下来
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
// 用于保存所有解析出来的Advisors集合对象
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 取出所有的Spring Bean的名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历判断
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 通过beanName去ioc容器中获取对应的Class对象
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 是否用@Aspect注解注释?
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 从Advice类中解析出所有的Advisor
// 会给每个Aspect类的advice方法创建一个Spring Advisor
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;
}
为了避免每次都去获取所有的beanName,解析判断,引入了缓存的机制;还有就是Aspect类是根据Spring Bean 是否被 @Aspect注解修饰来判断的。
接下来看一下上面的核心方法getAdvisors:
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取标记为Aspect的类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 获取切面类的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 校验切面类
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 获取到切面类中除了@PointCut注解外所有的方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 循环解析切面中的方法,获取当前方法的Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
// 保存获取到的Advisor
advisors.add(advisor);
}
}
// 如果寻找的Advisor不为空,且配置了Advisor延迟初始化,那么需要在首位加入同步实例化Advisor
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
接着看上面的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生成Advisor
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
Advisor的对象类型是InstantiationModelAwarePointcutAdvisorImpl,调用的构造方法如下:
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 切点表达式
this.declaredPointcut = declaredPointcut;
// 切面的Class对象
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
// 切面方法的名称
this.methodName = aspectJAdviceMethod.getName();
// 切面方法的参数类型
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
// 切面方法独享
this.aspectJAdviceMethod = aspectJAdviceMethod;
// aspectJ的Advisor工厂
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
// aspectJ的实例工厂
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);
}
}
而Advisor的初始化调用的是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方法:
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 获取切面类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
// 获取方法上注释的注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 检查是否是被@Aspect注释的类
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;
// 判断方法上注释的advice注解的类型
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;
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;
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;
}
到此为止,获取了被@Aspect注解注释的类中所有的advice,并根据advice方法上注解的类型生成了Advisor。此时的Advisors包含的是候选的Advisors,接下来还需要筛选匹配当前Bean的Advisors链。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取候选的Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选出匹配当前Bean的Advisors链
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 {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
// 获取IntroductionAdvisor类型的Advisor
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;
// 判断这个Advisor的PointCut是否可以应用到类中的某个方法上
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 使用calssfilter来匹配class
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// 如果匹配的是任意方法,则无需迭代
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
// 查找当前类及其祖宗类实现的所有接口
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
// 获取到所有的实现接口,然后遍历匹配接口的public方法
for (Class<?> clazz : classes) {
// 获取当前类的方法列表
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// 使用methodMatcher匹配方法,匹配成功即立即返回
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
筛选的工作主要由ClassFilter 和MethodMatcher 完成,比如AspectJExpressionPointcut的实现了ClassFilter和MethodMatcher接口,最终由AspectJ表达式解析。找到Advisors链之后,调用sortAdvisors方法进行排序,最后得到的就是目标类使用的Advisors链。
总结
Spring AOP 如何 获取对应 Bean 适配的Advisors 链的核心逻辑如下:
- 获取当前ioc容器中所有的 Aspect 类
- 给每个Aspect 类的advice 方法创建一个 Spring Advisor,这一步又能细分为
- 遍历所有advice 方法
- 解析方法的注解和pointcut
- 实例化 Advisor 对象
- 获取到候选的 Advisors并且缓存起来,方便下一次直接获取
- 从候选的 Advisors 中筛选出与目标类适配的Advisor
- 获取到Advisor 的切入点 pointcut
- 获取到当前 target类所有的 public 方法
- 遍历方法,通过切入点的methodMatcher匹配当前方法,只要有一个匹配成功,就相当于当前的Advisor 适配
- 对筛选之后的 Advisor 链进行排序
- 结束
解析Aspect实现Advice织入
前面得到了匹配当前Bean的Advisors链,接下来就需要调用createProxy方法来创建代理类对象,方法的实现如下:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 如果bean工厂为ConfigurableListableBeanFactory
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建ProxyBeanfactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 如果proxyTargetClass设置为true,都是使用Cglib生成代理类
// 否则,根据具体情况进行判断
if (!proxyFactory.isProxyTargetClass()) {
// 判断时根据接口还是类来生成代理类
if (shouldProxyTargetClass(beanClass, beanName)) {
// 根据类来生成代理类,使用Cglib代理
proxyFactory.setProxyTargetClass(true);
}
else {
// 根据接口生成代理类
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 类所有的Advisors数组
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 加入Advisor
proxyFactory.addAdvisors(advisors);
// 设置要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理
customizeProxyFactory(proxyFactory);
// 默认为false,代理配置后不允许修改代理的配置
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 根据工厂的各种配置生成代理类
return proxyFactory.getProxy(getProxyClassLoader());
}
基本流程如下:
- 获取当前类中的属性
- 添加代理接口
- 封装Advisor并加入到
ProxyFactory中 - 设置要代理的类
- Spring中为子类提供了定制的函数
customizeProxyFactory,子类可以在此函数中对ProxyFactory的进一步封装 - 获取代理操作
getProxy方法的实现如下,首先创建一个AopProxy,然后在获取代理类:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
其中创建AopProxy源码如下:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 判断使用JDK代理还是Cglib代理
// 如果proxyTargetClass为true,使用Cglib生成目标类的子类作为代理类
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果是实现接口,使用JDK动态代理生成代理类
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// JDK代理生活曾代理类
return new JdkDynamicAopProxy(config);
}
// 否则,使用Cglib生成代理类
return new ObjenesisCglibAopProxy(config);
}
else {
// 上面的条件都不满足,则使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
这一步之后我们根据ProxyConfig获取到了对应的AopProxy的实现类,分别是JdkDynamicAopProxy和ObjenesisCglibAopProxy。
JDK动态代理
JdkDynamicAopProxy的定义如下:
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
}
它的getProxy方法实现如下:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取完成的用于代理的接口集合
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 查找可能在提供的接口集上定义的任何equals或hashCode方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
最后也是调用了Proxy类的newProxyInstance方法来生成代理类对象。JDK动态代理中,用代理类的对应方法时,代理类实际上是通过invoke(Object proxy, Method method, Object[] args)方法来完成目标类方法的调用,并在里面进行一些代理类想做的增强操作。Spring AOP中,同样也是在invoke方法会完成AOP编织实现的封装。
invoke方法的实现如下:
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 如果当前方法为equals方法,并且接口中未定义该方法,则自动生成equals方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 如果当前方法为hashCode方法,并且接口中未定义该方法,则自动生成hashCode方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 有时目标类对象内部的自我调用无法实现切面增强,需要通过属性暴露代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标类
target = targetSource.getTarget();
// 获取目标类的Class对象
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取方法的拦截器链,即Advisors链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 如果没有拦截器,则直接调用目标类的对应方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 否则,先调用拦截器,在调用目标类方法
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 责任链模式,沿着Advisors链前进
retVal = invocation.proceed();
}
// 返回结果
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
invoke方法逻辑的核心是利用责任链模式,递归调用的方法,来完成advice的织入。
因此,关键的实现逻辑在proceed方法,实现如下:
@Override
@Nullable
public Object proceed() throws Throwable {
// 递归操作,从索引为-1的拦截器开始调用,并按序递增
// 当Advisors链的Advisor全部迭代调用完毕后,开始调用目标类中的对应方法,通过反射实现
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个要执行的Advisor
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
// 调用Advisor
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// 如果PointCut设置的是不是匹配具体的方法,则直接调用,不用匹配方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
我们来看看((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),这个方法有多种实现,其中一些我们熟悉的或者说需要关注的实现,对应的就是我们Advice的类型,或者说增强的时机。对应的有Before、After、After-returning、After-throwing、Around。
Cglib动态代理
Cglib代理和JDK代理在流程上相似,只是在具体实现上不一样。核心就是Enhancer和获得callbacks的过程。ObjenesisCglibAopProxy的getProxy方法的实现如下:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 获取父类的Class对象,即目标类的Class类对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建Cglib的Enhancer
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置父类
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// 设置回调
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 创建并返回代理类实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
至此,Spring AOP实现面向切面的过程就解析结束了,当返回对应的代理类后,后续程序获取到的bean就是代理类对象,而不是目标类对象。对于目标类方法的代调用,都会代理到代理类对象上,在方法执行的前后进行增强操作的织入。
对于JDK代理和Cglib代理的选择原则是:如果是单例的我们最好使用CGLib代理,如果是多例的我们最好使用JDK代理。
JDK在创建代理对象时的性能要高于CGLib代理,而生成代理对象的运行性能却比CGLib的低。
参考
Spring AOP 源码解析
Spring AOP - 注解方式使用介绍(长文详解)
向您图文并茂生动讲解Spring AOP 源码(2)
向您生动地讲解Spring AOP 源码(3)
Spring AOP 源码解析
本文详细解析了Spring AOP的工作原理,包括AOP自动代理的开启、触发时机、Bean匹配的Advisors链获取过程、Advisor的筛选逻辑、代理类的创建流程等内容。通过源码分析,介绍了JDK动态代理和Cglib动态代理的具体实现。
774

被折叠的 条评论
为什么被折叠?



