1、AOP简介
AOP:【动态代理】
指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;常用于日志处理,事物处理等统一性操作
2、使用说明
- 1、导入aop模块;Spring AOP:(spring-aspects)
- 2、定义一个业务逻辑类;在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
- 3、定义一个日志切面类:切面类里面的方法需要
动态感知业务类方法
运行到哪里然后执行;
前置通知(@Before)
:logStart:在目标方法运行之前运行后置通知(@After)
:logEnd:在目标方法运行结束之后运行(无论方法正常结束还是异常结束)返回通知(@AfterReturning)
:logReturn:在目标方法正常返回之后运行异常通知(@AfterThrowing)
:logException:在目标方法出现异常以后运行环绕通知(@Around)
:动态代理,手动推进目标方法运行(joinPoint.procced())
- 4、给切面类的目标方法标注何时何地运行(通知注解);
- 5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中;
- 6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
- 7、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
在Spring中很多的 @EnableXXX;
总结:
1)将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
2)在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
3)开启基于注解的aop模式;@EnableAspectJAutoProxy
3、AOP代理对象生成源码分析
(1)@EnableAspectJAutoProxy注解
在Spring
中很多的 @EnableXXX
类似注解,用于自动开启配置某些功能。分析源码时我们可以从这些注解入手
注意代码中的AspectJAutoProxyRegistrar
,spring
通常通过impot注册相关组件完成功能开启
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
# 此处的import为重点导入AspectJAutoProxyRegistrar组件
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
在AspectJAutoProxyRegistrar
内主要导入了AnnotationAwareAspectJAutoProxyCreator
组件,下面主要分析AnnotationAwareAspectJAutoProxyCreator具体操作及功能
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
# 导入了`AnnotationAwareAspectJAutoProxyCreator`组件
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
AnnotationAwareAspectJAutoProxyCreator
主要继承接口关系,从继承关系可以看到此组件最终实现了aware
和BeanPostProcessor
相关接口
AnnotationAwareAspectJAutoProxyCreator
extendsAspectJAwareAdvisorAutoProxyCreator
extendsAspectJAwareAdvisorAutoProxyCreator
extendsAbstractAdvisorAutoProxyCreator
extendsAbstractAutoProxyCreator
implementsSmartInstantiationAwareBeanPostProcessor
,BeanFactoryAware
关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory
在BeanFactoryAware
的setBeanFactory
内完成代理构造器的初始化,在SmartInstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
和postProcessAfterInitialization
内完成代理对象的包装,简单的看下下面代码
AbstractAdvisorAutoProxyCreator
内的setBeanFactory
部分代码
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
} else {
this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
}
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
AnnotationAwareAspectJAutoProxyCreator
内的setBeanFactory
部分代码
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
从
AbstractAdvisorAutoProxyCreator
和AnnotationAwareAspectJAutoProxyCreator
的两段代码中可以看出通过setBeanFactory
完成代理构造器的初始化
再看下面关于SmartInstantiationAwareBeanPostProcessor
接口实现的相关代码
AbstractAutoProxyCreator
内下面postProcessBeforeInstantiation
代码简单分析,
1、判断当前
bean
是否在advisedBeans
中(保存了所有切面拦截bean
)
2、是否是切面通知相关
的类Advice
、Pointcut
、Advisor
、AopInfrastructureBean
,如果是则直接加入需要加强集合advisedBeans
中设置为false这部分bean不需要加强。
3、然后判断该类是否值自定义加强类型getCustomTargetSource
若是则加强执行包装操作返回代理对象。
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if (beanName != null) {
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
再看AbstractAutoProxyCreator
内下面postProcessAfterInitialization
代码简单分析
在bean实例化初始化完成之后,会在下面方法中判断是否需要包装加强对象代理
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary
方法如下
加强判断步骤如下:
1、自定义加强
bean
和已经判断不需要加强的bean
直接返回
2、判断属于advice
等切面bean
和需要跳过的bean
直接返回bean
,并且将bean
加入不需要加强的bean
集合中
3、除以上情况外,判断此bean有无能处理改类的advice
拦截器,若有则将拦截器链排序生成代理对象返回
4、如果没有能处理的advice
则将bean加入无需加强bean
集合,直接返回改bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
适用的拦截器链条查找分析AbstractAdvisorAutoProxyCreator
中的findEligibleAdvisors
和AopUtils.findAdvisorsThatCanApply
方法。
主要逻辑为:遍历判断所有的加强器,是否适用于该bean,通过canApply
方法中的ClassFilter
接口的matches
方法判断,此处的ClassFilter
实现类为AspectJExpressionPointcut
通过此类的matches
匹配切入点是否适用该bean
AbstractAdvisorAutoProxyCreator
中的findEligibleAdvisors
protected List findEligibleAdvisors(Class> beanClass, String beanName) {
List candidateAdvisors = this.findCandidateAdvisors();
List eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
AopUtils.findAdvisorsThatCanApply
方法
public static List findAdvisorsThatCanApply(List candidateAdvisors, Class> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
} else {
List eligibleAdvisors = new LinkedList();
Iterator var3 = candidateAdvisors.iterator();
while(var3.hasNext()) {
Advisor candidate = (Advisor)var3.next();
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
Iterator var7 = candidateAdvisors.iterator();
while(var7.hasNext()) {
Advisor candidate = (Advisor)var7.next();
if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}
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;
} else {
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
} else {
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
}
Set> classes = new LinkedHashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
Iterator var6 = classes.iterator();
while(var6.hasNext()) {
Class> clazz = (Class)var6.next();
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
Method[] var9 = methods;
int var10 = methods.length;
for(int var11 = 0; var11 < var10; ++var11) {
Method method = var9[var11];
if (introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
}
}
AspectJExpressionPointcut
的matches
方法
public boolean matches(Class> targetClass) {
this.checkReadyToMatch();
try {
try {
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
} catch (ReflectionWorldException var4) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", var4);
PointcutExpression fallbackExpression = this.getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
} catch (Throwable var5) {
logger.debug("PointcutExpression matching rejected target class", var5);
}
return false;
}
PointcutExpression
实现方法
public boolean couldMatchJoinPointsInType(Class aClass) {
ResolvedType matchType = this.world.resolve(aClass.getName());
if (matchType.isMissing() && this.world instanceof ReflectionWorld) {
matchType = ((ReflectionWorld)this.world).resolveUsingClass(aClass);
}
ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, (Kind)null, this.matchContext, this.world);
boolean couldMatch = this.pointcut.fastMatch(info).maybeTrue();
return couldMatch;
}
代理对象生成分析:
通过ProxyFactory
根据相应属性创建代理对象,首先创建AopProxy
。
根据bean是否继承接口,生成ObjenesisCglibAopProxy
或者JdkDynamicAopProxy
然后getProxy
获取代理对象
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 (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
}
DefaultAopProxyFactory
根据bean是否继承接口判断生成对象时,通过JDK动态代理
还是Cglib
生成代理对象。ObjenesisCglibAopProxy
或者JdkDynamicAopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
我们看看ObjenesisCglibAopProxy
生成代理过程
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
Class> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class> proxySuperClass = rootClass;
int x;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class>[] additionalInterfaces = rootClass.getInterfaces();
Class[] var5 = additionalInterfaces;
int var6 = additionalInterfaces.length;
for(x = 0; x < var6; ++x) {
Class> additionalInterface = var5[x];
this.advised.addInterface(additionalInterface);
}
}
this.validateClassIfNecessary(proxySuperClass, classLoader);
Enhancer enhancer = this.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 CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = this.getCallbacks(rootClass);
Class>[] types = new Class[callbacks.length];
for(x = 0; x < types.length; ++x) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
return this.createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException var9) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var9);
} catch (IllegalArgumentException var10) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var10);
} catch (Throwable var11) {
throw new AopConfigException("Unexpected AOP exception", var11);
}
}
Callback[]
获取设置,获取的时候会通过AdvisedSupport
的getInterceptorsAndDynamicInterceptionAdvice
方法匹配目标bean中每个方法的拦截链条
,Callback[]
主要有FixedChainStaticTargetInterceptor
,DynamicAdvisedInterceptor
,HashCodeInterceptor
,HashCodeInterceptor
包含AdvisedSupport
(切面方法)并且实现MethodInterceptor
接口,在调用代理对象方法时动态拦截执行intercept
方法
private Callback[] getCallbacks(Class> rootClass) throws Exception {
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
Object targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
} else {
targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
Callback targetDispatcher = (Callback)(isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp());
Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
Callback[] callbacks;
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap(methods.length);
for(int x = 0; x < methods.length; ++x) {
List
总结:到此aop代理对象生成包装流程已经分析完成。主要由
@EnableAspectJAutoProxy
注解注入AnnotationAwareAspectJAutoProxyCreator
组件。该组件实现BeanFactoryAware
和SmartInstantiationAwareBeanPostProcessor
接口。
在BeanFactoryAware
的setBeanFactory
内完成代理构造器的初始化,在SmartInstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
和postProcessAfterInitialization
内完成代理对象的包装。
4、AOP拦截执行时机分析
上面我们已经分析了动态代理对象,含有MethodInterceptor
的拦截器集合,拦截器中又包含切面的方法。在执行intercept
时,首先通过this.advised.getInterceptorsAndDynamicInterceptionAdvice
获取拦截器(包装成实现org.aopalliance.intercept.MethodInterceptor
的实现类)方法链。然后创建CglibMethodInvocation
对象通过proceed
依次执行拦截链方法。
DynamicAdvisedInterceptor
的intercept
如下:
重点注意this.advised.getInterceptorsAndDynamicInterceptionAdvice
方法根据方法和目标类获取拦截器链
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;
Object var15;
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = this.getTarget();
if (target != null) {
targetClass = target.getClass();
}
List
分析this.advised.getInterceptorsAndDynamicInterceptionAdvice
方法,注意代码中AdvisorAdapterRegistry
利用registry.getInterceptors(advisor);
包装拦截器链
public List
DefaultAdvisorAdapterRegistry
的getInterceptors
方法通过AdvisorAdapter
适配器包装拦截器。下面代码可以看到主要的AdvisorAdapter
有MethodBeforeAdviceAdapter
,AfterReturningAdviceAdapter
,ThrowsAdviceAdapter
包装生成MethodBeforeAdviceInterceptor
,AfterReturningAdviceInterceptor
,ThrowsAdviceInterceptor
对象
public DefaultAdvisorAdapterRegistry() {
this.registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
this.registerAdvisorAdapter(new AfterReturningAdviceAdapter());
this.registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
下面我们可以看到包装过程获取所有的适配器,判断如果支持该advice则适配生成拦截器对象然后加入拦截器链
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor)advice);
}
Iterator var4 = this.adapters.iterator();
while(var4.hasNext()) {
AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
} else {
return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
}
在执行intercept
时,会创建CglibMethodInvocation
对象通过proceed
执行拦截方法。
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
我们看看MethodBeforeAdviceInterceptor
,AfterReturningAdviceInterceptor
,ThrowsAdviceInterceptor
拦截器invoke
的具体执行,下面三个方法都会执行mi.proceed();
关于递归执行CglibMethodInvocation
的proceed
方法知道执行索引等于链条的最后一个,MethodBeforeAdviceInterceptor
会先执行前置处理方法
MethodBeforeAdviceInterceptor
代码
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
MethodBeforeAdviceInterceptor
代码
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
ThrowsAdviceInterceptor
代码
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
} catch (Throwable var4) {
Method handlerMethod = this.getExceptionHandler(var4);
if (handlerMethod != null) {
this.invokeHandlerMethod(mi, var4, handlerMethod);
}
throw var4;
}
}
我们看看拦截器链的顺序,会递归到链条的末端连接器然后依次执行连接器链方法