
本文包含以下内容:
postProcessBeforeInstantiation 执行时机
postProcessBeforeInstantiation 的具体作用
目标方法div执行流程一:获取拦截器链
目标方法div执行流程二:拦截器链的调用流程分析
AOP 总结
前文回顾:
《Spring注解驱动开发之十三——AOP原理分析(一)@EnableAspectJAutoProxy注解干了什么》
1.postProcessBeforeInstantiation 执行时机


// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);
// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}
try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean '" + beanName + "'");}
if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}
populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {exposedObject = initializeBean(beanName, exposedObject, mbd);}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {Object cacheKey = getCacheKey(beanClass, beanName);if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.if (beanName != null) {TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {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;}

if (this.advisedBeans.containsKey(cacheKey)) {return null;}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}
protected boolean isInfrastructureClass(Class<?> beanClass) {boolean retVal = Advice.class.isAssignableFrom(beanClass) ||Pointcut.class.isAssignableFrom(beanClass) ||Advisor.class.isAssignableFrom(beanClass) ||AopInfrastructureBean.class.isAssignableFrom(beanClass);if (retVal && logger.isTraceEnabled()) {logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");}return retVal;}
protected boolean isInfrastructureClass(Class<?> beanClass) {// Previously we setProxyTargetClass(true) in the constructor, but that has too// broad an impact. Instead we now override isInfrastructureClass to avoid proxying// aspects. I'm not entirely happy with that as there is no good reason not// to advise aspects, except that it causes advice invocation to go through a// proxy, and if the aspect implements e.g the Ordered interface it will be// proxied by that interface and fail at runtime as the advice method is not// defined on the interface. We could potentially relax the restriction about// not advising aspects in the future.return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));}
public boolean isAspect(Class<?> clazz) {return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));}private boolean hasAspectAnnotation(Class<?> clazz) {return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);}
AspectJPointcutAdvisor 判断是否跳过
protected boolean shouldSkip(Class<?> beanClass, String beanName) {// TODO: Consider optimization by caching the list of the aspect namesList<Advisor> candidateAdvisors = findCandidateAdvisors();for (Advisor advisor : candidateAdvisors) {if (advisor instanceof AspectJPointcutAdvisor) {if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {return true;}}}return super.shouldSkip(beanClass, beanName);}

接下来会调用 new方法创建实例

3.然后创建完成后调用postProcessAfterInitialization函数
/*** Create a proxy with the configured interceptors if the bean is* identified as one to proxy by the subclass.* @see #getAdvicesAndAdvisorsForBean*/public Object postProcessAfterInitialization(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;}
看到 wrapIfNecessary 函数,如下
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (beanName != null && 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;}
3.1在wrapIfNecessary函数 中,判断targetSourcedBeans 列表里面是否,创建过当前Bean
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {return bean;}
3.2 判断修饰过的advisedBeans是否包含
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}
3.3与上面2.1 和2.2相同 判断是否代理,是否跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}
3.4接下来判断过后调用getAdvicesAndAdvisorsForBean函数中的findEligibleAdvisors 找到所有的能用的通知方法并进行排序
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();}
3.5 将当前Bean 放入advisedBeans 中表示已经被增强处理过并且通过createProxy 获得代理对象 并返回
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;}
通过代理工厂创建代码如下
protected Object createProxy(Class<?> beanClass, String beanName, 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());}
可以看到有CglibAopProxy 和 ObjenesisCglibAopProxy ,然后在容器获取对象时,将会进行返回代理对象。这就是postProcessBeforeInstantiation 具体作用

对容器获取到的对象,添加断点,查看div 目标方法的执行流程

可以看到如下图,所示,mathCalculator 对象是经过Cglib 代理后的对象

1.进入方法可以看到进入CglibAopProxy.intercept() 方法进行代理拦截,代码如下
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;Class<?> targetClass = null;Object target = null;try {if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// May be null. Get as late as possible to minimize the time we// "own" the target, in case it comes from a pool...target = getTarget();if (target != null) {targetClass = target.getClass();}List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// 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 = methodProxy.invoke(target, argsToUse);}else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal = processReturnType(proxy, target, method, retVal);return retVal;}finally {if (target != null) {releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}}
2.其核心是通过getInterceptorsAndDynamicInterceptionAdvice函数,获取拦截器列表,判断列表是否为空来进行不同的操作
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// 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 = methodProxy.invoke(target, argsToUse);}else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}
3.进入获取拦截器列表的函数
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, 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;}
4.看到getInterceptorsAndDynamicInterceptionAdvice函数,registry.getInterceptors(advisor);遍历所有的增强器,返回interceptorList
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, 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<Object>(config.getAdvisors().length);Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);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)) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor);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;}
5.核心在于registry.getInterceptors(advisor); 将增强器转为List<MethodInterceptor>;如果是MethodInterceptor,直接加入到集合中,如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;转换完成返回MethodInterceptor数组;
@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);Advice advice = advisor.getAdvice();if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) 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[interceptors.size()]);}
运行完成后,将获得拦截器如下所示,有5个:1个默认的4个自定义的增强方法

拦截器不为空,将会运行CglibMethodInvocation.proceed()方法
else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}
可以看到具体的process()函数代码如下
public Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);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.return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}
1.如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}
2.接着获取第0个Advice :org.springframework.aop.interceptor.ExposeInvocationInterceptor执行
else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
3.查看invoke()的代码如下,重复调用到这个mi.proceed() 使得取下一个拦截器,进行操作
private static final ThreadLocal<MethodInvocation> invocation =new NamedThreadLocal<MethodInvocation>("Current AOP method invocation");public Object invoke(MethodInvocation mi) throws Throwable {MethodInvocation oldInvocation = invocation.get();invocation.set(mi);try {return mi.proceed();}finally {invocation.set(oldInvocation);}}
流程如图所示:

4.再次调用proceed(),运行到AspectJAfterThrowingAdvice第二个拦截器:同样是调用invoke(this)
public Object invoke(MethodInvocation mi) throws Throwable {try {return mi.proceed();}catch (Throwable ex) {if (shouldInvokeOnThrowing(ex)) {invokeAdviceMethod(getJoinPointMatch(), null, ex);}throw ex;}}
流程如图所示:

5.再次调用proceed(),运行到AfterReturningAdviceInterceptor第三个拦截器:同样是调用invoke(this)
public Object invoke(MethodInvocation mi) throws Throwable {Object retVal = mi.proceed();this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());return retVal;}
流程图如下:

6.再次调用proceed(),运行到AspectJAfterAdvice第四个拦截器:同样是调用invoke(this),但是此处进行了finally ,无论如何都会运行advice的函数。
public Object invoke(MethodInvocation mi) throws Throwable {try {return mi.proceed();}finally {invokeAdviceMethod(getJoinPointMatch(), null, null);}}
流程图如下:

7.再次调用proceed(),运行到MethodBeforeAdviceInterceptor第五个拦截器:同样是调用invoke(this),但是此处进行了finally ,无论如何都会运行advice的before函数调用前置通知、以及目标函数。
@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );return mi.proceed();}
流程图如下:

8.再次运行proceed()函数检测到是最后一个拦截器,并且进行出栈操作。往上返回到上一级,由于第6步的proceed()方法返回就会触发finnaly 的函数进行 调用后置通知,流程图如下:

9.在第5步,可以看到代码,没有问题才会调用afterReturn 函数完成的回调,所以第6步发生异常直接跳到第4步的,捕获异常并且调用异常的回调方法。流程图如下:

1)、 @EnableAspectJAutoProxy 开启AOP功能
2)、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4)、容器的创建流程:
5)、执行目标方法:
1)、代理对象执行目标方法
2)、CglibAopProxy.intercept();
1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
3)、效果:
正常执行:前置通知-》目标方法-》后置通知-》返回通知
出现异常:前置通知-》目标方法-》后置通知-》异常通知
-END-

可以关注我的公众号,免费获取价值1980元学习资料
点击“在看”,学多少都不会忘~

本文分享自微信公众号 - 阿聪的全栈之路(gh_ffab7c84fb0c)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4134523/blog/4868805