AOP(Aspect-Oriented Programming) 面向切面编程。Spring Aop 在 Spring框架中的地位举足轻重,主要用于实现事务、缓存、安全等功能。
AOP的实现本质就是动态代理,下面从源码角度来分析spring的AOP实现原理
AOP的使用
下面是AOP的注解实现,也是SpringBoot中实现AOP最常见的方式
@Aspect
public class AspectTest {
@Pointcut("execution(public * com.miaosha.controller.*.*(..))")
public void aspect(){}
@Before("aspect()")
public void before(){
System.out.println("before aspect");
}
@After("aspect()")
public void after(){
System.out.println("after aspect");
}
}
上面这段代码的功能是对com.miaosha.controller包下面的每个类的每一个方法进行增强,增强的内容就是每个方法最前面打印"before aspect",最后打印"after aspect"
AOP实现的大致流程主要分为三个步骤:
- 创建AnnotationAwareAspectJAutoProxyCreator对象
- 扫描容器中的切面,创建PointcutAdvisor对象
- 生成代理类
1、创建AnnotationAwareAspectJAutoProxyCreator对象
AnnotationAwareAspectJAutoProxyCreator类是spring实现AOP至关重要的类,它是在SpringBoot自动装配的时候被加载的,自动装配之前已经详细讲过,这里可以看到有一个AopAutoConfiguration
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
public static class CglibAutoProxyConfiguration {
}
}
继续跟进 @EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {.....}
最后可以跟到
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
上述代码可以看到注册了一个切面相关BeanDefinition,正是上面提到的类:
AnnotationAwareAspectJAutoProxyCreator
这里只是创建BeanDefinition,并没有实例化和初始化该对象。那什么时候会触发呢?
该类继承的顶层接口为 BeanPostProcessor。BeanPostProcessor实现类会提前初始化,在自动装配解析完成之后,直接实例化,不像普通bean一样
2: 扫描容器中的切面,创建PointcutAdvisor对象
这个过程出现在AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法中,在springboot创建bean的实例化bean之前被执行
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
........
try {
// 遍历postprocessor,执行postProcessBeforeInstantiation方法
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);
}
//开始正式创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
.......
}
跟进一下resolveBeforeInstantiation方法
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
.........
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
.........
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//遍历所有的后处理器,执行其postProcessBeforeInstantiation方法
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;
}
我们可以看到后处理器集合中包含了AnnotationAwareAspectJAutoProxyCreator
下面来详细看看AnnotationAwareAspectJAutoProxyCreator中postProcessBeforeInstantiation做了什么
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans用于存储不可代理的bean,如果包含直接返回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//判断当前bean是否可以被代理,然后存入advisedBeans
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.
//到这里说明该bean可以被代理,所以去获取自定义目标类,如果没有定义,则跳过。
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
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;
}
来看一下判定 bean 是否被代理的方法依据:
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
private boolean hasAspectAnnotation(Class<?> clazz) {
//判定当前类是否有 Aspect 注解,如果有,则不能被代理
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
//判定当前bean是否是 Advice、Pointcut、Advisor、AopInfrastructureBean等子类或实现类,如果是,则不能被代理
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;
}
重点来看 shouldSkip方法:
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
//获取所有的候选顾问类 Advisor
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()方法来获取所有的候选 advisor:
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
//获得 Advisor 实现类
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
//将@Aspect注解类, 解析成Advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
继续跟进buildAspectJAdvisors方法,会触发
ReflectiveAspectJAdvisorFactory中的getAdvisors方法:
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//从 aspectMetadata 中获取 Aspect()标注的类 class对象
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取Aspect()标注的类名
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<>();
//遍历该类所有方法,根据方法判断是否能获取到对应 pointCut,如果有,则生成 advisor 对象
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
//获取 @DeclareParents 注解修饰的属性(并不常用)
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
继续来看getAdvisor方法:
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//根据候选方法名,来获取对应的 pointCut
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//如果能获取到 pointCut,则将切点表达式 expressionPointcut、当前
对象ReflectiveAspectJAdvisorFactory、 方法名等包装成 advisor 对象
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
}
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
//定义class对象数组,如果方法中有以下注解中任何一种,则返回该注解
Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class<?> c : classesToLookFor) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
InstantiationModelAwarePointcutAdvisorImpl的构造方法会触发构造通知对象:
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//......
//根据注解类型,匹配对应的通知类型
switch (aspectJAnnotation.getAnnotationType()) {
//前置通知
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());
}
//异常通知
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
//环绕通知
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//切面
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
//......
}
可以看到,根据@Aspect类中方法的注解类型,生成对应的advice,并通过通知的构造方法,将通知增强方法,切面表达式传入到通知当中。
从这里可以看到例子中的两个增强逻辑对应生成了两个advisor被缓存起来了,其中的advice类也分别是BeforeAdvice和AfterAdvice
到这里InstantiationModelAwarePointcutAdvisorImpl对象构造完毕。
3: 生成代理类
这个过程发生在初始化之后,这也是spring最后一个后处理器拓展接口
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//执行postProcessBeforeInitialization逻辑
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//初始化
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
//执行postProcessAfterInitialization逻辑
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
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;
}
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;
}
// 如果有合适的advisor就使用代理类
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 List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//对所有的advisor进行筛选
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
我们可以看到之前定义的两个增强逻辑被筛选了出来
然后就是生成代理类
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());
}
跟踪代码,这里可以看到Springboot中默认的动态代理方式为JDK动态代理hasNoUserSuppliedProxyInterfaces表明只要类有实现一定的接口就会使用JDK动态代理方式
CGLIB动态代理适用于没有实现接口的类进行动态代理,它使用的是继承的方式
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);
}
}
到这里,AOP创建动态代理对象的逻辑已经完成了,但是我们并没有看出来增强的逻辑是怎么加入到动态代理类中的
这里先来复习一下Java中动态代理实现的过程,自定义一个handler实现InvicationHandler,其中包含委托类实例,实现一个接口方法invoke(),其主要用于写增强逻辑,并且用反射的方法实现原方法
public class StuInvocationHandler<T> implements InvocationHandler {
//invocationHandler持有的被代理对象
T target;
public StuInvocationHandler(T target) {
this.target = target;
}
/**
* proxy:代表动态代理对象
* method:代表正在执行的方法
* args:代表调用目标方法时传入的实参
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" +method.getName() + "方法");
*/
//代理过程中插入监测方法,计算该方法耗时
MonitorUtil.start();
Object result = method.invoke(target, args);
MonitorUtil.finish(method.getName());
return result;
}
}
public static void main(String[] args) {
//创建一个实例对象,这个对象是被代理的对象
Person zhangsan = new Student("张三");
//创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new StuInvocationHandler<Person>(zhangsan);
//创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
//代理执行上交班费的方法
stuProxy.giveMoney();
}
我们再来看看spring中JDK动态代理类的实现,从getProxy方法中可以看到,spring同样也是使用的
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)方法,传入相同类型的三个参数
public Object getProxy(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方法,它串联起了各个advisor的增强逻辑,从注释就可以看到,这个invoke也是实现的InvocationHandler.invoke方法,
/**
* Implementation of {@code InvocationHandler.invoke}.
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
............
// 获取该方法的advisor拦截链
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.
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 {
// 创建一个启动项
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 启动项开始执行拦截链
retVal = invocation.proceed();
}
.......
}
}
这里重点来看看启动项ReflectiveMethodInvocation.proceed()方法,其中interceptorsAndDynamicMethodMatchers数据结构存储的就是该method适用的advisor的集合,整个执行过程是一个遍历拦截链,递归的过程,所谓的拦截链就是advisor的集合,只不过是按照before,after顺序排列好的
public Object proceed() throws Throwable {
// 如果拦截链执行到了最后,则反射执行method原本的逻辑
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) 如果拦截链执行完,反射执行method自身的逻辑,
invokeJoinpoint()方法
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
// 反射执行method方法
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
(2) 遍历拦截链,执行每个advisor的增强逻辑
BeforeAdvice的执行
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
........
public Object invoke(MethodInvocation mi) throws Throwable {
//先执行before的逻辑
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
//递归向下传递Invocation对象
return mi.proceed();
}
.........
}
AfterAdvice的执行,这里非常巧妙的使用finally,后置执行增强逻辑
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
........
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//先向下递归传递
return mi.proceed();
}
finally {
//执行after的增强逻辑
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
.......
}
这样看是不是特别清楚了
画图来表示一下,假如现在有一个拦截链如图所示,2个before,2个after
那么根据拦截链的执行逻辑,其中advisor的增强逻辑的执行顺序为
JDK动态代理的方法就是这样被增强的
所以,总结来说,Spring的AOP本质就是动态代理,它的巧妙之处就在于将增强的逻辑封装成了拦截器,实现了一个拦截链,在invoke时,使用拦截器链增强方法