Spring框架进阶Spring V3.0 AOP源码分析流程
Posted 烟锁迷城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶Spring V3.0 AOP源码分析流程相关的知识,希望对你有一定的参考价值。
目录
1、总体分析
在Spring的设计之中,AOP发生在实例化的过程中,在符合代理要求的情况下,返回的类从原生类改为代理类。
整个代理切面方法会被组成一个代理链,通过递归的方式,将它们按顺序执行。
总体流程大致为
- 寻找入口
- 选择策略
- 调用方法
- 触发通知
2、源码分析
回到上一节DI之中,可以看到,之前提到过在doCreateBean方法之中,有两个方法,一个是实例化方法createBeanInstance,一个是依赖注入方法pupolateBean。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException
// Instantiate the bean.
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton())
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
if (instanceWrapper == null)
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
//获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class)
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
//调用PostProcessor后置处理器
synchronized (mbd.postProcessingLock)
if (!mbd.postProcessed)
try
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
catch (Throwable ex)
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
mbd.postProcessed = true;
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//向容器中缓存单例模式的Bean对象,以防循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure)
if (logger.isDebugEnabled())
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// Initialize the bean instance.
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
catch (Throwable ex)
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName()))
throw (BeanCreationException) ex;
else
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
if (earlySingletonExposure)
//获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null)
//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean)
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans)
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))
actualDependentBeans.add(dependentBean);
if (!actualDependentBeans.isEmpty())
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
// Register bean as disposable.
//注册完成依赖注入的Bean
try
registerDisposableBeanIfNecessary(beanName, bean, mbd);
catch (BeanDefinitionValidationException ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
return exposedObject;
在createBeanInstance方法中,起到实例化作用的是initializeBean,这个方法返回了需要的类
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
// Make sure bean class is actually resolved at this point.
//检查确认Bean是可实例化的
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//使用工厂方法对Bean进行实例化
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed())
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null)
return obtainFromSupplier(instanceSupplier, beanName);
if (mbd.getFactoryMethodName() != null)
//调用工厂方法实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
// Shortcut when re-creating the same bean...
//使用容器的自动装配方法进行实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null)
synchronized (mbd.constructorArgumentLock)
if (mbd.resolvedConstructorOrFactoryMethod != null)
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
if (resolved)
if (autowireNecessary)
//配置了自动装配属性,使用容器的自动装配实例化
//容器的自动装配是根据参数类型匹配Bean的构造方法
return autowireConstructor(beanName, mbd, null, null);
else
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
// Need to determine the constructor...
//使用Bean的构造方法进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))
//使用容器的自动装配特性,调用匹配的构造方法实例化
return autowireConstructor(beanName, mbd, ctors, args);
// No special handling: simply use no-arg constructor.
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
在initializeBean方法中,可以看到,
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
这是一段lambda表达式,在其中明显有一个实例化策略getInstantiationStrategy(),这个策略是什么呢?是来自于DefaultAutowireCapableBeanFactory的一个成员变量,Cglib代理策略,这是默认的代理策略
private InstantiationStrategy instantiationStrategy =
new CglibSubclassingInstantiationStrategy();
protected InstantiationStrategy getInstantiationStrategy()
return this.instantiationStrategy;
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)
try
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK标准的安全管理API
if (System.getSecurityManager() != null)
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
else
//将实例化的对象封装起来
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
catch (Throwable ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
那么doCreateBean方法中createBeanInstance方法返回的封装BeanWrapper是否就会被直接返回呢?并不是
Object exposedObject = bean,之中的bean来源于BeanWrapper,的确是实例化或是从实例缓存中拿到的,但是它还经过了两个步骤,其一是initializeBean,其二是循环依赖的检测,才会返回。
循环依赖自不必说,如果创建的Bean和缓存中的bean是一致的,就会被缓存中的替换。
但是很显然,那个从initializeBean(初始化Bean)方法中得到的Bean也替换了exposedObject,在这之中又进行了什么操作呢?
Object exposedObject = bean;
try
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
catch (Throwable ex)
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName()))
throw (BeanCreationException) ex;
else
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
if (earlySingletonExposure)
//获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null)
//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean)
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName))
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans)
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))
actualDependentBeans.add(dependentBean);
if (!actualDependentBeans.isEmpty())
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
// Register bean as disposable.
//注册完成依赖注入的Bean
try
registerDisposableBeanIfNecessary(beanName, bean, mbd);
catch (BeanDefinitionValidationException ex)
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
return exposedObject;
initializeBean方法的参数有三个,是CreateBeanInstance中的initializeBean方法的一个重载方法,三个参数的initializeBean会额外传递一个已经完成依赖注入的类,这意味着暴露类中的一些参数是这个方法所需要的。
applyBeanPostProcessorsBeforeInitialization:初始化前置处理
invokeInitMethods:初始化
applyBeanPostProcessorsAfterInitialization:初始化后置处理
代理一定是初始化之后才进行代理,所以看后置处理方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
//JDK的安全机制验证权限
if (System.getSecurityManager() != null)
//实现PrivilegedAction接口的匿名内部类
AccessController.doPrivileged((PrivilegedAction<Object>) () ->
invokeAwareMethods(beanName, bean);
return null;
, getAccessControlContext());
else
//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
//回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
//文件中通过init-method属性指定的
try
invokeInitMethods(beanName, wrappedBean, mbd);
catch (Throwable ex)
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
//对BeanPostProcessor后置处理器的postProcessAfterInitialization
//回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic())
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
可以看到,applyBeanPostProcessorsAfterInitialization方法里的实现,比较关键的是自定义的处理操作,也就是BeanPostProcessor的postProcessAfterInitialization方法,实际上这个方法的实现类有很多,但我们只看AbstractAutoProxyCreator实现类的,因为这是代理创建者
@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors())
//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
//初始化之后做一些自定义的处理操作
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null)
return result;
result = current;
return result;
AbstractAutoProxyCreator类看关键方法wrapIfNecessary(bean, beanName, cacheKey)
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException
if (bean != null)
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey))
return wrapIfNecessary(bean, beanName, cacheKey);
return bean;
warpIfNecessary方法的前半部分是一些判断读取缓存的操作,关键在于getAdvicesAndAdvisorsForBean方法,这个方法是去获取对象对应的通知。
如果获取到通知,就返回代理类,如果没有通知,那么就不必代理,继续返回原来的初始化类即可
所以接下来的操作就分为读取通知,进行代理
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;
// Create proxy if we have advice.
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;
获取到所有的通知,如果通知为空,则返回空,反之返回通知队列
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;
可以看到,排序的方法是一个比较器提供的,在这个比较器中,执行doCompare方法,按照优先级进行排序
protected List<Advisor> sortAdvisors(List<Advisor> advisors)
AnnotationAwareOrderComparator.sort(advisors);
return advisors;
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider)
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
if (p1 && !p2)
return -1;
else if (p2 && !p1)
return 1;
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
读取通知结束之后,就进行代理操作。
回到wrapIfNecessary方法中,可以看到,如果通知,就进行代理操作,createProxy方法
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;
可以看到。这里proxyFactory放入了一些数据,包括通知,目标资源等,最后执行
proxyFactory.getProxy方法
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 (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);
return proxyFactory.getProxy(getProxyClassLoader());
在ProFactory的getProxy中,可以得到创建方法,继续向下,可以看到,如果有接口继承,就使用JDK代理,否则使用CGlib方式
public Object getProxy(@Nullable ClassLoader classLoader)
return createAopProxy().getProxy(classLoader);
protected final synchronized AopProxy createAopProxy()
if (!this.active)
activate();
return getAopProxyFactory().createAopProxy(this);
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException
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.");
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass))
return new JdkDynamicAopProxy(config);
return new ObjenesisCglibAopProxy(config);
else
return new JdkDynamicAopProxy(config);
接下来以JDK代理为例。
getProxy方法来自JdkDynamicAopProxy,实际上这个方法来自于JdkDynamicAopProxy的接口AopProxy,目的是统一两种代理方式获取代理的入口。
newProxyInstance,最后创建代理类的方法
public Object getProxy(@Nullable ClassLoader classLoader)
if (logger.isDebugEnabled())
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
在完成代理类的实现之后,真正要关注的还是代理的invoke方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
这里应用的是责任链模式,将通知装载到责任链之中,依照顺序进行执行。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try
//eqauls()方法,具目标对象未实现此方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method))
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
//hashCode()方法,具目标对象未实现此方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))
// The target does not implement the hashCode() method itself.
return hashCode();
else if (method.getDeclaringClass() == DecoratingProxy.class)
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
//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)
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
//获得目标对象的类
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//获取可以应用到此方法上的Interceptor列表
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
//如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
if (chain.isEmpty())
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
else
// We need to create a method invocation...
//创建MethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
// Massage return value if necessary.
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);
getInterceptorsAndDynamicInterceptionAdvice方法中,将方法Method作为生成缓存key的参数,进入到MethodCacheKey类中可以看到,其内部是由method和其hashcode组成,这里的目的是重写equal和hashcode方法,为放入到Map容器中做准备(至于为什么要重写equal和hashcode是一个小小的知识点,这里不做赘述)。
key生成完成之后,将在methodCache缓存中进行查找,那么这个缓存是什么呢?
是一个map,一个32大小的ConcurrentHashMap,且禁止序列化。
Map<MethodCacheKey, List<Object>> methodCache
如果没有得到对应的缓存,就获取到通知列表,并放入缓存中,如果获取到了,就直接返回即可
那么接下来的重点就是AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法,获取通知列表
private transient Map<MethodCacheKey, List<Object>> methodCache;
public AdvisedSupport()
this.methodCache = new ConcurrentHashMap<>(32);
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass)
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null)
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
return cached;
getInterceptorsAndDynamicInterceptionAdvice方法返回的就是一个Object列表,interceptorList,那么在这里放入的是什么呢?是MethodInterceptor
可以看到addAll方法放入的是MethodInterceptor,add方法放入的是InterceptorAndDynamicMethodMatcher,实际上其内部是MethodInterceptor和MethodMatcher两个属性,本质依旧是MethodInterceptor。
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass)
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
//查看是否包含IntroductionAdvisor
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
//这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors())
if (advisor instanceof PointcutAdvisor)
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass))
//这个地方这两个方法的位置可以互换下
//将Advisor转化成Interceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
//检查当前advisor的pointcut是否可以匹配当前方法
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions))
if (mm.isRuntime())
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors)
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
else
interceptorList.addAll(Arrays.asList(interceptors));
else if (advisor instanceof IntroductionAdvisor)
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass))
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
else
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
return interceptorList;
得到拦截器之后,回到 JdkDynamicAopProxy之中,继续向下
可以看到,接下来的关键是如果拦截器不为空,则执行invocation.proceed,这是一个调用器,可以视作责任链模式的上下文,作为依次执行拦截器的启动
if (chain.isEmpty())
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
else
// We need to create a method invocation...
//创建MethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
// Massage return value if necessary.
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;
ReflectiveMethodInvocation类的process方法,可以看到这里面的操作已经是类似递归调用的责任链方式。
如果全部拦截都执行完了,则返回joinpoint切点,否则当前游标自增,获取到当前应该执行的拦截器。如果符合动态匹配标准,调用拦截器的invoke方法,否则递归调用,获取到下一个拦截器。
那么很明显,精华部分在于dm.interceptor.invoke方法
public Object proceed() throws Throwable
// We start with an index of -1 and increment early.
//如果Interceptor执行完了,则执行joinPoint
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1)
return invokeJoinpoint();
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果要动态匹配joinPoint
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher)
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//动态匹配:运行时参数是否满足匹配条件
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments))
return dm.interceptor.invoke(this);
else
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
return proceed();
else
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//执行当前Intercetpor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
事实上,dm.interceptor.invoke有很多的实现,可以挑几个具有代表性的看看
首先带有Before的MethodBeforeAdviceInterceptor
可以看到,这个方法的构造会把要执行的目标对象放入,在执行invoke方法之前,会把目标对象的before方法,即真正要执行的方法先行执行,然后执行自身的process方法,将责任链向下推进
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable
private MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice)
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
@Override
public Object invoke(MethodInvocation mi) throws Throwable
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
接下来看一个after的拦截器AfterReturningAdviceInterceptor
可以清晰地看到,这里先执行到责任链的下一个拦截器的方法process,然后才执行目标对象要执行的after方法,巧妙地保证了执行的顺序
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable
private final AfterReturningAdvice advice;
/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice)
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
@Override
public Object invoke(MethodInvocation mi) throws Throwable
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
然后是afterThrow的拦截器AspectJAfterThrowingAdvice ,这里可以看到,是在抛错的情况下,才会执行对应的目标方法
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif)
super(aspectJBeforeAdviceMethod, pointcut, aif);
@Override
public boolean isBeforeAdvice()
return false;
@Override
public boolean isAfterAdvice()
return true;
@Override
public void setThrowingName(String name)
setThrowingNameNoCheck(name);
@Override
public Object invoke(MethodInvocation mi) throws Throwable
try
return mi.proceed();
catch (Throwable ex)
if (shouldInvokeOnThrowing(ex))
invokeAdviceMethod(getJoinPointMatch(), null, ex);
throw ex;
/**
* In AspectJ semantics, after throwing advice that specifies a throwing clause
* is only invoked if the thrown exception is a subtype of the given throwing type.
*/
private boolean shouldInvokeOnThrowing(Throwable ex)
return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
这样整个责任链都可以不用考虑after和before的执行顺序,而是直接按照顺序调用即可,非常巧妙
3、流程总结
3.1、创建代理类
AbstractAutowireCapableBeanFactory:
initializeBean:在初始化和依赖注入之后执行的方法,创建暴露给外部的类,替换初始化之后的类。
AbstractAutowireCapableBeanFactory:
applyBeanPostProcessorsAfterInitialization:初始化的后置处理,代理在此完成
AbstractAutoProxyCreator:
wrapIfNecessary:读取通知方法getAdvicesAndAdvisorsForBean,进行代理方法createProxy,如果没有通知,则不必代理
3.1.1、读取通知
AbstractAdvisorAutoProxyCreator:
getAdvicesAndAdvisorsForBean:获取通知
AbstractAdvisorAutoProxyCreator:
findEligibleAdvisors:获取通知,去重,排序
AbstractAdvisorAutoProxyCreator:
sortAdvisors:通知排序,使用AnnotationAwareOrderComparator进行排序
3.1.2、进行代理
AbstractAdvisorAutoProxyCreator:
createProxy:创建代理类
ProxyFactory:
getProxy:创建代理对象
DefaultAopProxyFactory:
createAopProxy:根据条件创建代理方式
JdkDynamicAopProxy(AopProxy):
newProxyInstance:创建代理
3.2、代码织入
JdkDynamicAopProxy(AopProxy):
invoke:继承InvocationHandler之后必然会重写的方法,用于实现代理
3.2.1、拦截器
JdkDynamicAopProxy(AopProxy):
getInterceptorsAndDynamicInterceptionAdvice:AdvisedSupport的方法,目的是将所有的通知同城一个拦截器,这里用到了责任链模式,将以method作为key,存放至methodCache,一个CurrentHashMap之中,如果没有获取到其中的缓存,就去调用getInterceptorsAndDynamicInterceptionAdvice来获取
AdvisedSupport:
getInterceptorsAndDynamicInterceptionAdvice:将advisor全部转化为MethodInterceptor,装载至列表中返回给缓存
3.2.2、调用器
JdkDynamicAopProxy(AopProxy):
proceed:拦截器链的上下文,属于被封装好的调用器ReflectiveMethodInvocation,启动整个拦截器链条
ReflectiveMethodInvocation:
invoke:在责任链中的每一个符合条件的拦截器都会调用此方法,执行回调响应
3.3、响应回调
MethodBeforeAdviceInterceptor:此处仅为例子,代表响应前置
before:目标对象的执行任务,真正要执行的方法,前置处理
process:责任链上下文,调用下一个责任链中的拦截器
AfterReturningAdviceInterceptor:此处仅为例子,代表响应后置
process:责任链上下文,调用下一个责任链中的拦截器
after:目标对象的执行任务,真正要执行的方法,后置处理
AspectJAfterThrowingAdvice:此处仅为例子,代表响应抛错
process:责任链上下文,调用下一个责任链中的拦截器
afterThrow:目标对象的执行任务,真正要执行的方法,仅在有错误的情况下执行
4、核心思想
整个AOP最核心的思想,除了代理,就是责任链中的拦截器,这里面包含两个类,MethodInterceptor(拦截器)和MethodInvocation(调用器)。
MethodInterceptor:其内部的方法Invoke是代理增强的方法,在每一个MethodInterceptor的invoke方法之中,都依照通知的响应先后,决定是先执行目标方法还是执行责任链中的下一个拦截器,如before类型的拦截器,就先执行before,然后执行process方法调用下一个拦截器,after则反之
MethodInvocation:其内部的方法process串起了全部的拦截器,通过内部游标的自增计算,完成了全部拦截器的顺序调用。
以上是关于Spring框架进阶Spring V3.0 AOP源码分析流程的主要内容,如果未能解决你的问题,请参考以下文章