AOP中的一些概念
AOP代理实现
Spring基于注解实现AOP的类是AnnotationAwareAspectJAutoProxyCreator,该类的继承体系为
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor类,也就是上文所述的Bean创建的前后处理器。AbstractAutoProxyCreator中的postProcessBeforeInstantiation()和postProcessAfterInitialization方法是实现AOP功能的关键方法。
postProcessBeforeInstantiation()在创建bean之前执行,获取全部的AOP代理类并解析缓存。postProcessAfterInitialization在bean初始化之后执行,实现类的代理。
代理前的准备
AbstractAutoProxyCreator的postProcessBeforeInstantiation()方法如下:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// shouldSkip()方法获取并解析已定义好的代理
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
}
shouldSkip()方法由子类AspectJAwareAdvisorAutoProxyCreator覆盖实现:
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 获取切面信息
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
findCandidateAdvisors()方法在AbstractAdvisorAutoProxyCreator中定义,该方法可以获取并解析非注解实现的AOP代理,而在AnnotationAwareAspectJAutoProxyCreator中覆盖实现的findCandidateAdvisors()方法,不仅可以获取并解析非注解实现的AOP代理,也可以获取并解析注解实现的AOP代理
protected List<Advisor> findCandidateAdvisors() {
// 获取并解析非注解实现的AOP代理
List<Advisor> advisors = super.findCandidateAdvisors();
// 获取并解析注解实现的AOP代理
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
buildAspectJAdvisors()方法是可以获取并解析注解实现的AOP代理,并将解析好的结果放在缓存中,后续再获取列表时,可以直接从缓存中获取:
- 先遍历所有的类
- 判断该类是否是切面类
- 获取切面类Aspect的切面列表
- 保存切面类Aspect的切面列表到缓存advisorsCache中
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(
this.beanFactory, Object.class, true, false);
// 遍历所有的类
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 判断该类是否为切面类
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);
// 获取并解析切面类,得到一个切面列表
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 {
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;
}
getAdvisors()方法在ReflectiveAspectJAdvisorFactory类中,该方法遍历切面类的所有切面方法,然后解析出切面,并添加到切面列表中
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
// 遍历该类的切面方法
List<Advisor> advisors = new ArrayList<>();
// getAdvisorMethods()获取该类的所有切面方法,并排序(按照切面优先级顺序排序)
for (Method method : getAdvisorMethods(aspectClass)) {
// 解析出切面
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);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
getAdvisor()方法则是创建一个InstantiationModelAwarePointcutAdvisorImpl对象并返回,其中解析切面方法是在该类的构造方法中完成
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;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
InstantiationModelAwarePointcutAdvisorImpl在其构造方法中完成切面方法的解析
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 参数赋值
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
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);
}
}
// 通过aspectJAdvisorFactory.getAdvice()获取一个Advice
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()方法是在ReflectiveAspectJAdvisorFactory类中,通过获取方法上的注解,并和AOP预先定义好的注解进行匹配,最后可以得到对应的增强类Advice
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;
}
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;
// 注解和AOP预定义的注解进行匹配,然后返回对应的增强类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);
}
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
实现代理
AbstractAutoProxyCreator的postProcessAfterInitialization()方法如下:
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;
}
wrapIfNecessary()主要有两步,首先匹配所有的切面列表,然后再使用匹配到的切面列表创建代理
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;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 匹配切面列表
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;
}
获取匹配的切面列表
getAdvicesAndAdvisorsForBean()由子类AbstractAdvisorAutoProxyCreator实现
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()首先查询出所有的切面列表,然后再遍历得出匹配当前类的切面列表。findCandidateAdvisors()方法由子类AnnotationAwareAspectJAutoProxyCreator实现,从上文创建切面列表中可以发现,本次调用findCandidateAdvisors()可以直接从缓存中获取全部的切面列表,而不需要再创建。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 查询所有的切面列表
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 得到匹配当前bean的切面列表
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findAdvisorsThatCanApply()方法则是通过AopUtils工具类的findAdvisorsThatCanApply()方法获取匹配当前bean的切面列表
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()方法也并未实现真正的匹配逻辑,而是遍历了所有增强器,再调用canApply()方法获取匹配该bean的增强器,而canApply()方法则继续向下调用另外一个重载的canApply()方法
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;
}
// 将匹配当前bean的增强器加到结果列表中
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 {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
canApply()遍历该bean的所有方法,然后一一和增强器匹配,匹配上则返回true
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<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 遍历该bean的所有方法
for (Method method : methods) {
// 增强器和方法匹配
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
创建代理
得到匹配的切面列表后,再返回到wrapIfNecessary()方调用的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();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
if (shouldProxyTargetClass(beanClass, beanName)) {
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);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 创建代理
return proxyFactory.getProxy(classLoader);
}
// proxyFactory中的getProxy()方法
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
// ProxyFactory父类ProxyCreatorSupport中的createAopProxy()方法
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
createAopProxy()是AopProxyFactory接口中定义的方法,具体实现在DefaultAopProxyFactory类中,createAopProxy()方法可以创建JDK代理和CGLB代理两种代理。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// 创建JDK代理
return new JdkDynamicAopProxy(config);
}
// 创建CGLB代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 创建JDK代理
return new JdkDynamicAopProxy(config);
}
}
创建好AopProxy代理对象后,再调用getProxy()方法获取代理,以JDK为例
// 构造方法,代理对象
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
// 获取代理类应该实现的代理接口
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
// 获取代理
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 返回代理对象,代理类为JdkDynamicAopProxy
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
因为JdkDynamicAopProxy类实现了InvocationHandler接口的invoke()方法,JdkDynamicAopProxy本身就是代理。
执行代理方法
当调用代理的方法时,实际上调用的是JdkDynamicAopProxy的invoke()方法
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 {
// 不对equals和hashCode方法代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
// DecoratingProxy接口
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// Advised接口
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised接口.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
// 返回值
Object retVal;
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// target对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 切面列表的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// ReflectiveMethodInvocation控制拦截链chain一个一个执行
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
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()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
ReflectiveMethodInvocation拦截链的执行
1. Advisor和Advice的关系
一个Advisor(InstantiationModelAwarePointcutAdvisorImpl)是封装了一个Advice(五种通知),同时还封装了对应的Pointcut对象(AspectJExpressionPointcut)
2. Advice和MethodInterceptor的关系
MethodInterceptor提供了一个接口功能叫intercept,使用此方法完成对执行方法的拦截,方便执行增强功能,Advice是MethodInterceptor的父接口。
Advice有五种通知@Around,@Before,@After,@Around,@AfterReturning,@AfterThrowing,其中
- AspectJAfterAdvice(@After)
- AspectJAroundAdvice(@Around)
- AspectJAfterThrowingAdvice(@AfterThrowing)
实现了MethodInterceptor接口,而另外两种通知,没有直接实现MethodInterceptor接口,需要使用适配器
- AfterReturningAdviceAdapter(@AfterReturning转为AfterReturningAdviceInterceptor)
- MethodBeforeAdviceAdapter(@Before转为MethodBeforeAdviceInterceptor)
与MethodInterceptor接口建立联系。
// 支持的适配器
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
// 在invoke方法中获取拦截器链时会完成适配器的转换,整体的调用链为:
// 1.org.springframework.aop.framework.JdkDynamicAopProxy.invoke()
// 2.org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
// 3.org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
// 4.org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry.getInterceptors()
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
// 直接实现了MethodInterceptor的Advice
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 需要使用适配器的Advice
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
3. Advice的顺序
Advice的正常的执行顺序为@Around(before) –> @Before –> 逻辑 –> @AfterReturning -> @After -> @Around(after)
而Advice在列表中存放的顺序,则是在ReflectiveAspectJAdvisorFactory的getAdvisors()方法中遍历方法,通过getAdvisorMethods(aspectClass)获取待遍历的方法时排序
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
if (methods.size() > 1) {
// 对方法进行排序,adviceMethodComparator为排序器
methods.sort(adviceMethodComparator);
}
return methods;
}
// 排序器(ReflectiveAspectJAdvisorFactory类中)
private static final Comparator<Method> adviceMethodComparator;
static {
// 该段注释解释@After在@AfterReturning和@AfterThrowing之后执行
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
// an @After advice method will actually be invoked after @AfterReturning and
// @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
// invokes proceed() in a `try` block and only invokes the @After advice method
// in a corresponding `finally` block.
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}
4. 执行拦截链
以@Around,@Before,@After三个注解,拦截器链执行逻辑为:
- 首先在chain中的顺序为Around,Before,After
- <获取拦截器,获取后currentInterceptorIndex=2> 获取第一个拦截器Around,执行invoke()方法
// 拦截器坐标,记录推进到了哪一个拦截器
private int currentInterceptorIndex = -1;
public Object proceed() throws Throwable {
// 拦截器执行完,执行目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个拦截器
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)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
// 执行拦截器的invoke()方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
- <Around注解> AspectJAroundAdvice的invoke方法如下,传入的参数this被封装为ProceedingJoinPoint继续调用invokeAdviceMethod和invokeAdviceMethodWithGivenArgs方法
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
- <Around注解> invokeAdviceMethodWithGivenArgs在调用aspectJAdviceMethod.invoke时,会进入到自定义的@Around切面中
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
- <Around注解> 进入到自定义的@Around切面逻辑并执行,调用proceedingJoinPoint.proceed()方法再获取下一个拦截器
@Around("myPointCut()")
public Object printAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("around-before");
// proceedingJoinPoint是上游传入的this
Object result = proceedingJoinPoint.proceed();
System.out.println("around-after");
return result;
}
- <获取拦截器 获取后currentInterceptorIndex=3> 再次进入ReflectiveMethodInvocation的proceed获取下一个拦截器@Before
- <Before注解> MethodBeforeAdviceInterceptor的invoke方法如下,先执行自定义的@Before切面逻辑,然后再获取下一个拦截器
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
- <获取拦截器 获取后currentInterceptorIndex=4> 再次进入ReflectiveMethodInvocation的proceed获取下一个拦截器@After
- <After注解> AspectJAfterAdvice的invoke方法如下,先执行proceed()方法继续获取下一个拦截器,再执行@After切面逻辑
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
- <获取拦截器> 执行真正的逻辑方法
- <After注解> 执行完After的切面逻辑,结束After注解执行
- <Before注解> 执行完MethodBeforeAdviceInterceptor的proceed方法,结束Before注解执行
- <Around注解> 执行完自定义切面逻辑中proceedingJoinPoint.proceed(),获得了真正逻辑的返回结果,再执行自定义切面逻辑的后半部分,然后结束Around注解执行
- 所有切面执行完,返回结果