Spring之AOP
(一)AOP相关介绍:
1. AOP概念
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程.
作用:在不修改目标类代码的前提下,可以通过AOP技术去增强目标类的功能。通过【预编译式】或者【运行期动态代理】实现程序功能的统一维护的一种技术. 而达到对目标类进行无感知的功能增强. 因此在项目开发中,我们可以利用AOP, 对业务代码中【业务逻辑】和【系统逻辑】进行隔离,从而使得【业务逻辑】和【系统逻辑】之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
为什么使用AOP?AOP采取横向抽取机制,补充了 传统纵向继承体系(OOP)无法解决的重复性代码优化(性能监视、事务管理、安全检查、缓存),将业务逻辑和系统处理的代码(关闭连接、事务管理、操作日志记录)解耦。
AOP与纵向继承:
优势:
重复性代码被抽取出来之后,维护更加方便.
不想修改原有代码前提下,可以动态横向添加共性代码
1.2 AOP相关术语:
命名 | 定义 |
Joinpoint(连接点) | 所谓连接点是指被增强的方法. |
Pointcut(切入点) | 要对哪些Jointpoint进行拦截的定义. |
Advice(通知/增强) |
拦截到Jointpoint之后所要做的事情,也就是具体进行增强的内容. 通知分为前置通知,后置通知,异常通知,最终通知, 环绕通知.(切面要完成的功能) |
Introdtion(引介) |
引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态地增加一些方法或Field. |
Target(目标对象) |
代理的实际目标对象 |
Weaving(织入) |
把增强应用到目标对象来创建新的代理对象的过程。 |
Proxy(代理) |
一个类被AOP织入增强后就产生一个结果代理类。 |
切面(Aspect) | 切入点和通知的结合(pointCut与Around)。 |
Advisor(通知器或者顾问) | 和切面相似。 |
1.3 Spring AOP原理:
SpringAop共分为四个阶段: 创建代理对象, 拦截目标对象, 调用代理对象, 调用目标对象
创建代理对象: 在Spring中,通过getBean方法创建Bean实例,在创建完实例之后, Spring容器根据AOP的配置去匹配目标类的类名,如果目标类满足切面规则,则会调用ProxyFactory,根据目标对象自动选择不同的代理策略(JDK Proxy与CglibProxy),创建代理Bean并缓存到IOC容器.。
拦截目标对象: 当用户调用目标对象的某个方法时, 将会被一个叫做AopProxy的对象拦截, AopProxy的getProxy()方法会返回JdkDynamicAopProxy或者CglibAopProxy。Spring将所有的调用策略封装到了这两个对象中, 它们实现了InvocationHandler接口, 在这个接口的invoke方法中,会触发MethodInvocation的Proceed方法, 随后按顺序执行所有符合APO拦截器规则的拦截器链.
调用代理对象: SpringAOP拦截器链中的每个元素被命名为MethodInterceptor(切面配置中的Advice通知). MethodInterceptor.invoke方法执行织入部分的代码
调用目标对象:当currentInterceptorIndex==interceptorsAndDynamicMethodMatchers.size() - 1 然后调用invokeJoinpoint方法完成对目标方法的调用。
目标对象到代理对象的创建过程:
(二)代理:
静态代理与动态代理:
静态代理的作用:为其他对象提供一种代理以控制对这个对象的访问。另一种情况是,有时一个客户不想或者不能直接引用另外一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
2.1 JDK动态代理:
JDK动态代理是这样一种class: 在运行时生成class,在生成它时我们必须提供一组interface给它,然后该class就会声明它实现了这些interface。因此我们可以将该class的实例当作这些interface中的任何一个来用。当然,这个动态代理其实就是一个proxy,它不会替我们实质性的工作,在生成它的实例时我们必须提供一个handler,由它接管实际的工作。
JDK动态代理:Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类(接口):
(1)Interface InvocationHandler:该接口定义了一个方法public object invoke(Object obj, Method method, Object[] args) 在实际使用时第一个object一般是指代理类,method是被代理的方法,args为该方法的参数数组,这个抽象方法在代理类中动态实现。
(2)Proxy:该类即为动态代理类,其中主要包括以下内容:
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) , 通过该方法返回代理类的一个实例,返回后的代理实例可以当作代理类来使用。
JDK动态代理创建步骤:
-
创建一个接口Invocation Handler的类,它必须实现invoke方法
-
创建被代理的类及接口
-
通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)创建一个代理
-
通过代理调用方法
JDK动态代理代码实现:
public interface Subject { void myNewRequest(); }
目标类:
public class RealSubject implements Subject{ @Override public void myNewRequest() { System.out.println("new request from realSubject"); } }
代理增强类:
public class DynamicSubjectInvocationHandler implements InvocationHandler { private Object sub; public DynamicSubjectInvocationHandler(Object sub){ this.sub = sub; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy: "+ proxy.getClass()); System.out.println("before:"+method); method.invoke(sub,args); System.out.println("after:"+method); return null; } }
客户端:
public class DynamicProxyClient { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); InvocationHandler invocationHandler = new DynamicSubjectInvocationHandler(realSubject); Class<?> classType = invocationHandler.getClass(); /* If the proxy class defined by the given loader implementing the given interfaces exists, this will simply return the cached copy; otherwise, it will create the proxy class via the ProxyClassFactory */ Subject subject = (Subject) Proxy.newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(),invocationHandler); subject.myNewRequest(); }
测试结果:
proxy: class com.sun.proxy.$Proxy0
before:public abstract void com.spring.dynamicProxy.Subject.myNewRequest()
new request from realSubject
after:public abstract void com.spring.dynamicProxy.Subject.myNewRequest()
2.2 Cglib动态代理:
CGLIB:目标对象没有实现接口的功能,无法通过JDK动态代理实现,这个时候可以创建目标对象的子类对象,在子类对象中重写目标对象的方法,以此来完成功能的增强。
代码实现:
public class RealSubject { public void myNewRequest() { System.out.println("new request from realSubject"); } }
获取代理类的实现:
public class MyProxyUtils { public static RealSubject getProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealSubject.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if("myNewRequest".equalsIgnoreCase(method.getName())){ System.out.println("前置增强"); } return methodProxy.invokeSuper(o,objects); } }); RealSubject proxy = (RealSubject) enhancer.create(); return proxy; } }
测试代码:
public class client { public static void main(String[] args) { RealSubject proxy = MyProxyUtils.getProxy(); proxy.myNewRequest(); } }
测试结果:
前置增强
new request from realSubject
2.3 JDK动态代理和Cglib动态代理的区别
1.JDK动态代理是Java自带的,cglib动态代理是第三方jar包提供的。
2.JDK动态代理是针对【拥有接口的目标类】进行动态代理的,Cglib是【对父类的方法进行覆盖,非final类】都可以进行动态代理。但是Spring优先使用JDK动态代理。
3.JDK动态代理实现的逻辑是目标类和代理类都实现同一个接口,目标类和代理类是平级的。而Cglib动态代理实现的逻辑是给目标类生个孩子(子类,也就是代理类),目标类和代理类是父子关系。
4.JDK动态代理在早期的JDK1.6左右性能比cglib差,但是在JDK1.8以后cglib和jdk的动态代理性能基本上差不多。甚至jdk动态代理性能更加的优越。
JDK动态代理是通过Proxy的newProxyInstance方法返回代理对象,通过InvocationHandler的实现类,重写invoke方法,完成对目标类接口的增强。
cglib动态代理是使用enhancer,对目标类的拦截主要封装在了enhancer的setCallBack回调方法中,该方法的有一个参数methodInterceptor,该参数通过重写intercept方法以此对目标方法进行拦截与增强。
(三)AOP原理
3.1 AOP运行样例
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; @Aspect public class SimpleAspect { // 定义切入点表达式 @Pointcut("execution(* com.gzz.spring.aspectJ.UserServiceImpl.*(..))") private void pointcut(){ } // 前置通知 @Before("pointcut()") public void before(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("执行" + methodName + "的前置通知(@Before)..."); } // 后置通知 @After("pointcut()") public void after(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("执行" + methodName + "的后置通知(@After)..."); } // 环绕通知 @Around("pointcut()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws InterruptedException { String methodName = proceedingJoinPoint.getSignature().getName(); System.out.println("执行" + methodName + "的环绕通知前(@Around)..."); try { long startTime = System.currentTimeMillis(); Object result = proceedingJoinPoint.proceed(); long endTime = System.currentTimeMillis(); System.out.println(methodName + "()方法耗时: " + (endTime - startTime) + "毫秒"+"; 环绕通知后(@Around)..."); return result; } catch (Throwable throwable) { throwable.printStackTrace(); return null; } } // 返回通知 @AfterReturning("pointcut()") public void afterReturning(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("执行" + methodName + "的后置返回通知(@AfterReturning)..."); } @AfterThrowing("pointcut()") public void afterThrowing(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("执行" + methodName + "的后置返回通知(@afterThrowing)..."); } }
public interface UserService { public void addUser(); }
定义目标对象:
import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; @Component public class UserServiceImpl implements UserService{ @Override public void addUser() { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("新增用户..."); } }
定义配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "com.gzz") public class SpringConfiguration { public SpringConfiguration() { System.out.println("spring 容器启动"); } @Bean public SimpleAspect simpleAspect(){ return new SimpleAspect(); } @Bean public UserService userService(){ return new UserServiceImpl(); } }
测试:
import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class SpringConfigurationTest { @Test public void test1(){ //创建纯注解方式的spring 容器 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class); UserService userService = (UserService) applicationContext.getBean("userService"); userService.addUser(); } }
2、@Before通知
3、程序逻辑
4、@AfterReturning通知
5、@After通知
6、环绕通知后
2、@Before通知
3、@AfterThrowing异常通知
4、@After通知
异常日志
3.2 AOP创建流程
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //调用aware接口 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //应用BeanPostProcessor的postProcessBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //执行初始化方法(先调用InitializingBean的afterPropertiesSet,再调用init-method属性指定的初始化方法) invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //应用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理对象生成) wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
AbstractAutoProxyCreator:
@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; }
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; } // Advice/Pointcut/Advisor/AopInfrastructureBean接口的beanClass不进行代理以及对beanName为aop内的切面名也不进行代理 // 此处可查看子类复写的shouldSkip()方法 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 查找对代理类相关的advisor对象集合,此处就与ponit-cut表达式有关了 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 对相应的advisor不为空才采取代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 通过jdk动态代理或者cglib动态代理,产生代理对象 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; }
AbstractAdvisorAutoProxyCreator:
@Override @Nullable 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) { // 候选的Advisors List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 合格的Advisors List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //排完序就决定了通知的执行先后顺序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
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); //如果没有使用CGLib代理 if (!proxyFactory.isProxyTargetClass()) { // 是否可能使用CGLib代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { // 查看beanClass对应的类是否含有InitializingBean.class/DisposableBean.class/Aware.class接口 // 无则采用JDK动态代理,有则采用CGLib动态代理 evaluateProxyInterfaces(beanClass, proxyFactory); } } // 获得所有关联的Advisor集合(该分支待补充) Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // 此处的targetSource一般为SingletonTargetSource proxyFactory.setTargetSource(targetSource); // 空的实现 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); // 是否设置预过滤模式,此处针对本文为true if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 获取使用JDK动态代理或者cglib动态代理产生的对象 return proxyFactory.getProxy(getProxyClassLoader()); }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); //如果没有使用CGLib代理 if (!proxyFactory.isProxyTargetClass()) { // 是否可能使用CGLib代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { // 查看beanClass对应的类是否含有InitializingBean.class/DisposableBean.class/Aware.class接口 // 无则采用JDK动态代理,有则采用CGLib动态代理 evaluateProxyInterfaces(beanClass, proxyFactory); } } // 获得所有关联的Advisor集合(该分支待补充) Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); // 此处的targetSource一般为SingletonTargetSource proxyFactory.setTargetSource(targetSource); // 空的实现 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); // 是否设置预过滤模式,此处针对本文为true if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 获取使用JDK动态代理或者cglib动态代理产生的对象 return proxyFactory.getProxy(getProxyClassLoader()); }
Aop创建代理流程图:
总结:
在AbstractAutoWireCapableBeanFactory的initializeBean方法中,调用applyBeanPostProcessorAfterInitialization方法,进而调用beanProcessor的postProcessAfterInitialization方法,该钩子方法调用AbtsractAutoProxyCreator的wrapIfNecessary进行创建代理。wrapIfNecessary方法中会通过getAdvicesAndAdvisorsForBean方法查找到所有的advisors并进行排序. 具体查找的过程利用pointcut进行匹配。之后通过ProxyFactory创建代理,具体创建代理的策略有JDK动态代理与CGLIB动态代理。
3.3 AOP执行流程
// org.springframework.aop.framework.JdkDynamicAopProxy.invoke public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; // 1.获取到目标对象,也就是被代理对象的引用 TargetSource targetSource = this.advised.targetSource; Object target = null; try { // 如果目标对象未实现equals()方法,则不需要代理 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(); } // 如果方法是DecoratingProxy类型,也不需要拦截器执行 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; // 2. 如果exposeProxy属性值为true,则将代理对象暴露到ThreadLocal中 // exposeProxy是通过注解@EnableAspectJAutoProxy(exposeProxy = true)进行指定的,如果配置为true, // 则可以使用AopContext.currentProxy()获取到代理对象. 在Spring事务方法自调用的时候经常使用到. if (this.advised.exposeProxy) { // 将代理对象暴露到ThreadLocal中 oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // 3.获得目标对象实例 target = targetSource.getTarget(); // 获取目标对象的类型 Class<?> targetClass = (target != null ? target.getClass() : null); // 4.获得目标方法对应的拦截器链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 5.如果对应的拦截器链为空,也就是没有可以应用到此方法的通知(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 { // 6.如果拦截器链不为空,则需要创建一个MethodInvocation(方法调用对象) MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // 调用其proceed方法,实际上是调用ReflectiveMethodInvocation.proceed()方法 retVal = invocation.proceed(); } // 7.必要时转换返回值 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. // 恢复ThreadLocal中的旧代理对象 AopContext.setCurrentProxy(oldProxy); } } }
获取拦截器链:
// org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); // 1、首先从缓存中查找是否存在拦截器链 // private transient Map<MethodCacheKey, List<Object>> methodCache; 存放方法Method ==> 拦截器链集合的对应关系 List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { // 2、如果缓存中不存在拦截器链,则委托getInterceptorsAndDynamicInterceptionAdvice()方法继续查找 cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass); // 3、将前面一个步骤找到的拦截器链存入缓存中 this.methodCache.put(cacheKey, cached); } // 4、如果缓存中存在拦截器链的话,则直接返回 return cached; }
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. // 使用单例模式创建DefaultAdvisorAdapterRegistry实例 AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); // 从config中获取所有的advisors增强器 Advisor[] advisors = config.getAdvisors(); // 保存拦截器集合,长度就是增强器的总数量 List<Object> interceptorList = new ArrayList<>(advisors.length); // 目标类 Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); // 判断是否包含IntroductionAdvisor类型的增强器 Boolean hasIntroductions = null; // 遍历advisors数组,根据不同类型的Advisor做不同的处理 for (Advisor advisor : advisors) { // 如果advisor是PointcutAdvisor类型,判断advisor能否应用到目标方法 if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); // 检查当前advisor的pointcut是否可以匹配当前方法 boolean match; if (mm instanceof IntroductionAwareMethodMatcher) { if (hasIntroductions == null) { hasIntroductions = hasMatchingIntroductions(advisors, actualClass); } match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions); } else { match = mm.matches(method, actualClass); } // 如果匹配的话,将增强器转换成MethodInterceptor拦截器对象 if (match) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); 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)); } } } } // 如果advisor是IntroductionAdvisor类型,判断advisor能否应用到目标类 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; }
将增强器转换成MethodInterceptor拦截器对象:
//DefaultAdvisorAdapterRegistry#getInterceptors()方法: public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<>(3); Advice advice = advisor.getAdvice(); // 如果是MethodInterceptor类型的通知,则直接加入集合中 if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } // 通过适配器将advisor转换为MethodInterceptor拦截器 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]); }
执行拦截器与目标方法:
// ReflectiveMethodInvocation.proceed() // 开始执行拦截器链增强方法 public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 1.当前拦截器下标:从-1的位置开始, 直到满足索引下标 =(拦截器的长度 -1)的条件(所有拦截器都执行完毕),此时需要执行目标方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { // 执行目标方法 return invokeJoinpoint(); } // 2.每次调用时,将索引的值递增,从拦截器链中获取下一个需要执行的拦截器 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; // 目标类所属类型 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 { // 如果匹配失败,则会跳过当前拦截器interceptor,则会调用proceed()方法执行拦截器链中的下一个拦截器的处理 return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. // 3.只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
aop执行流程图:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!