【小家Spring】Spring AOP各个组件概述与总结【Pointcut、Advice、Advisor、Advised、TargetSource、AdvisorChainFactory...】

article/2025/10/29 18:20:41

每篇一句

基础技术总是枯燥但有价值的。数学、算法、网络、存储等基础技术吃得越透,越容易服务上层的各种衍生技术或产品

相关阅读

【小家Spring】Spring AOP原理使用的基础类打点(AopInfrastructureBean、ProxyProcessorSupport、Advised、AjType)
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)
【小家Spring】探索Spring AOP中aopalliance的Joinpoint、MethodInvocation、Interceptor、MethodInterceptor…
【小家Spring】详解Spring AOP的底层代理JdkDynamicAopProxy和ObjenesisCglibAopProxy的源码分析(介绍CGLIB使用中的坑)
【小家Spring】Spring AOP中@Pointcut切入点表达式最全面使用介绍
【小家Spring】Spring AOP之Advisor、PointcutAdvisor、IntroductionAdvisor、IntroductionInterceptor(引介增强)

前言

Spring AOP作为整个Spring体系最最重要的分支之一,若干技术都是基于它的(比如事务、异步、缓存等)

前面通过好几篇文章,已经把Spring AOP内部的的运行流程等基本都叙述了一遍,但是通过小伙伴们反馈,还是晕头转向的:类太多了,且很多概念感觉很模糊,不知道咋用的。

因此本文就站在一个更高的角度,对Spring AOP部分用到的一些组件,进行概念上的、宏观上的进行一个概述和分析总结。

Spring AOP概述

AOP(Aspect-Oriented Programming)面向切面编程,它是在OOP的基础上诞生的一种编程模型。我们可以通熟易懂的理解为:在程序中具有公共特性的某些类/某些方法上进行拦截, 在方法执行的前面/后面/执行结果返回后 增加执行一些方法。

在Spring中,实现的底层原理是通过动态代理 / CGLIB来做的

Spring AOP组件总结

1、Pointcut

这个类位于 org.springframework.aop 包中,它的作用就是定义切面的匹配点。(简单的说就是我去切哪些类、哪些方法…) 在 Spring Aop 中匹配的点主要是 class 与 method 这两个方面, 分别为ClassFilterMethodFilter

// 由 ClassFilter 与 MethodMatcher 组成的 pointcut
public interface Pointcut {// 类过滤器, 可以知道哪些类需要拦截ClassFilter getClassFilter();// 方法匹配器, 可以知道哪些方法需要拦截MethodMatcher getMethodMatcher();// 匹配所有对象的 PointcutPointcut TRUE = TruePointcut.INSTANCE;
}

在 Spring 中主要有以下几个类,介绍如下:

  1. NameMatchMethodPointcut:通过刚发名进行精确匹配的。 (PS: 其中 ClassFilter = ClassFilter.TRUE)
  2. ControlFlowPointcut:根据在当前线程的堆栈信息中方法名来决定是否切入某个方法(效率较低)
  3. ComposablePointcut:组合模式的 Pointcut, 主要分成两种: 1.组合中所有都匹配算成功 2. 组合中都不匹配才算成功
  4. JdkRegexpMethodPointcut:通过 正则表达式来匹配方法(PS: ClassFilter.TRUE)
  5. AspectJExpressionPointcut:通过 AspectJ 包中的组件进行方法的匹配(切点表达式)
  6. TransactionAttributeSourcePointcut:通过 TransactionAttributeSource 在 类的方法上提取事务注解的属性 @Transactional 来判断是否匹配, 提取到则说明匹配, 提取不到则说明匹配不成功
  7. AnnotationJCacheOperationSource:支持JSR107的cache相关注解的支持

上述中的 TransactionAttributeSourcePointcut 其实就是Spring注解式事务的 Pointcut。通过匹配方法上 @Transactional 标签来确定方法是否匹配;(事务篇会分析它的源码)

2、Advice

Advice: 建议忠告, 劝告, 通知。它其实最开始是 aopalliance 包中的一个空接口, 接口的存在主要是为了标示对应类为 Advice;

在Spring Aop 中 Advice 其实表示的是在 Pointcut 点上应该执行的方法。而这些方法可以在目标方法之前、之后、包裹、抛出异常等等任何地方执行。

Advice: 其主要分成两类:普通advice 与Interceptor/MethodInterceptor

普通Advice :
  1. MethodBeforeAdvice:在目标方法之前执行,主要实现有:
    1. AspectJMethodBeoreAdvice:这是通过解析被 org.aspectj.lang.annotation.Before 注解注释的方法时解析成的Advice
  2. AfterReturningAdvice:在切面方法执行后(这里的执行后指不向外抛异常, 否则的话就应该是 AspectJAfterThrowingAdvice 这种 Advice) 主要实现有:
    1. AspectJAfterAdvice:解析 AspectJ 中的 @After 注解来生成的 Advice(PS: 在java中的实现其实就是在 finally 方法中调用以下对应要执行的方法)
    2. AspectJAfterReturningAdvice:解析 AspectJ 中的@AfterReturning 属性来生成的 Advice(PS: 若切面方法抛出异常, 则这里的方法就将不执行)
    3. AspectJAfterThrowingAdvice:解析 AspectJ 中的 @AfterThrowing 属性来生成的 Advice(PS: 若切面方法抛出异常, 则这里的方法就执行)
  3. AspectJAroundAdvice:将执行类 MethodInvocation(MethodInvocation其实就是Pointcut) 进行包裹起来, 并控制其执行的 Advice (其中 Jdk中中 Proxy 使用ReflectiveMethodInvocation, 而 Cglib 则使用 CglibMethodInvocation)

注意,注意,注意:在Proxy中最终执行的其实都是MethodInterceptor,因此这些Advice最终都是交给 AdvisorAdapter -> 将 advice 适配成 MethodInterceptor

MethodInterceptor:
  1. ExposeInvocationInterceptor:将当前 MethodInvocation 放到当前线程对应的 ThreadLoadMap里面的, 这是一个默认的 Interceptor, 在AspectJAwareAdvisorAutoProxy获取何时的 Advisor 时会调用自己的 extendAdvisors 方法, 从而将 ExposeInvocationInterceptor 方法执行链表的第一位。它的实现非常简单:
	private ExposeInvocationInterceptor() {}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {MethodInvocation oldInvocation = invocation.get();invocation.set(mi);try {return mi.proceed();}finally {invocation.set(oldInvocation);}}
  1. SimpleTraceInterceptor:Spring内置了很多日志跟踪的拦截器,父类AbstractTraceInterceptor有多个日志实现:
    在这里插入图片描述
    CustomizableTraceInterceptor:对方法调用前后拦截一下
public class Main {public static void main(String[] args) {ProxyFactory factory = new ProxyFactory(new Person());factory.setProxyTargetClass(true); // 强制私用CGLIB 以保证我们的Person方法也能正常调用// 记录日志的切面CustomizableTraceInterceptoradvice = new CustomizableTraceInterceptor();// 切点+通知(注意:此处放的是复合切面)Advisor advisor = new DefaultPointcutAdvisor(advice);factory.addAdvisor(advisor);Person p = (Person) factory.getProxy();p.run();p.say();}
}
输出:
17:28:56.054 [main] TRACE o.s.a.i.CustomizableTraceInterceptor - Entering method 'run' of class [com.fsx.bean.Person]
我在run...
17:28:56.078 [main] TRACE o.s.a.i.CustomizableTraceInterceptor - Exiting method 'run' of class [com.fsx.bean.Person]
17:28:56.079 [main] TRACE o.s.a.i.CustomizableTraceInterceptor - Entering method 'say' of class [com.fsx.bean.Person]
我在say...
17:28:56.079 [main] TRACE o.s.a.i.CustomizableTraceInterceptor - Exiting method 'say' of class [com.fsx.bean.Person]

SimpleTraceInterceptor:正常效果同上,异常也是同样的输出,没CustomizableTraceInterceptor强大
DebugInterceptor:SimpleTraceInterceptor的子类。有个计数器,记录被拦截的次数,且可以这样获取出来advice.getCount()
PerformanceMonitorInterceptor:记录每个方法运行的时长,还是比较有用的.

我在run...
17:37:10.853 [main] TRACE o.s.a.i.PerformanceMonitorInterceptor - StopWatch 'com.fsx.bean.Person.run': running time (millis) = 29
我在say...
17:37:10.854 [main] TRACE o.s.a.i.PerformanceMonitorInterceptor - StopWatch 'com.fsx.bean.Person.say': running time (millis) = 0
  1. AfterReturningAdviceInterceptor:这个类其实就是将 AfterReturningAdvice 包裹成 MethodInterceptor 的适配类, 而做对应适配工作的就是 AfterReturningAdviceAdapter
  2. MethodBeforeAdviceInterceptor:这个类其实就是将 MethodBeforeAdvice 包裹成 MethodInterceptor 的适配类, 而做对应适配工作的就是 MethodBeforeAdviceAdapter
  3. ThrowsAdviceInterceptor:这个类其实就是将 ThrowsAdvice 包裹成 MethodInterceptor 的适配类, 而做对应适配工作的就是 ThrowsAdviceAdapter
  4. TransactionInterceptor:这个类就是大名鼎鼎的注解式事务的工具类, 这个类通过获取注解在方法上的 @Transactional 注解的信息来决定是否开启事务的 MethodInterceptor (PS: 在注解式事务编程中将详细叙述)

1、无论通过aop命名空间/AspectJ注解注释的方法, 其最终都将解析成对应的 Advice
2、所有解析的 Advice 最终都将适配成 MethodInterceptor, 并在 JdkDynamicAopProxy/CglibAopProxy中进行统一调用

3、Advisor

Advisor 其实它就是 Pointcut 与 Advice 的组合, Advice 是执行的方法, 而要知道方法何时执行, 则 Advice 必需与 Pointcut 组合在一起, 这就诞生了 Advisor 这个类

打个比方:
Advice表示建议
Pointcut表示建议的地点
Advisor表示建议者(它知道去哪建议,且知道是什么建议)

  1. PointcutAdvisor: 我们在 Spring 中常用的 Advisor, 包含一个 Pointcut 与一个 advice
  2. AspectJPointcutAdvisor: 这个是 Spring 解析 aop 命名空间时生成的 Advisor(与之对应的 Advice 是 AspectJMethodBeforeAdvice, AspectJAfterAdvice, AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice, Pointcut 则是AspectJExpressionPointcut), 对于这个类的解析是在 ConfigBeanDefinitionParser
  3. InstantiationModelAwarePointcutAdvisorImpl: 这个Advisor是在Spring解析被 @AspectJ注解注释的类时生成的 Advisor, 而这个 Advisor中的 Pointcut与Advice都是由 ReflectiveAspectJAdvisorFactory 来解析生成的(与之对应的 Advice 是 AspectJMethodBeforeAdvice, AspectJAfterAdvice, AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice, Pointcut 则是AspectJExpressionPointcut), 解析的步骤是: AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors() -> BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() -> ReflectiveAspectJAdvisorFactory.getAdvisors() -> ReflectiveAspectJAdvisorFactory.getAdvisor() 最终生成了 InstantiationModelAwarePointcutAdvisorImpl (当然包括里面的 Pointcut 与 advice 也都是由 ReflectiveAspectJAdvisorFactory 解析生成的)
  4. TransactionAttributeSourceAdvisor: 一个基于 MethodInterceptor(其实是 TransactionInterceptor)与 TransactionAttributeSourcePointcut 的Advisor, 而这个类最常与 TransactionProxyFactoryBean使用
  5. DefaultPointcutAdvisor: 最常用的 Advisor, 在使用编程式aop时, 很多时候会将 Advice / MethodInterceptor 转换成 DefaultPointcutAdvisor
  6. NameMatchMethodPointcutAdvisor: 这个是在使用 NameMatchPointcutAdvisor时创建的 Advisor, 主要是通过 方法名来匹配是否执行 Advice
  7. RegexpMethodPointcutAdvisor: 基于正则表达式来匹配 Pointcut 的 Advisor, 其中的 Pointcut 默认是 JdkRegexpMethodPointcut
  8. Spring 中解析 aop:advisor 时生成的 Advisor, 见 ConfigBeanDefinitionParser.parseAdvisor
  9. BeanFactoryTransactionAttributeSourceAdvisor: 在注解式事务编程时, 主要是由 BeanFactoryTransactionAttributeSourceAdvisor, AnnotationTransactionAttributeSource, TransactionInterceptor 组合起来进行事务的操作(PS: AnnotationTransactionAttributeSource 主要是解析方法上的 @Transactional注解, TransactionInterceptor 是个 MethodInterceptor, 是正真操作事务的地方, 而BeanFactoryTransactionAttributeSourceAdvisor 其实起着组合它们的作用); <- 与之相似的还有 BeanFactoryCacheOperationSourceAdvisor

4、Advised

Advised: 已经被建议的对。

// 这个 Advised 接口的实现着主要是代理生成的对象与AdvisedSupport (Advised的支持器)
public interface Advised extends TargetClassAware {// 这个 frozen 决定是否 AdvisedSupport 里面配置的信息是否改变boolean isFrozen();// 是否代理指定的类, 而不是一些 Interfaceboolean isProxyTargetClass();// 返回代理的接口Class<?>[] getProxiedInterfaces();// 判断这个接口是否是被代理的接口boolean isInterfaceProxied(Class<?> intf);// 设置代理的目标对象void setTargetSource(TargetSource targetSource);// 获取代理的对象TargetSource getTargetSource();// 判断是否需要将 代理的对象暴露到 ThreadLocal中, 而获取对应的代理对象则通过 AopContext 获取void setExposeProxy(boolean exposeProxy);// 返回是否应该暴露 代理对象boolean isExposeProxy();// 设置 Advisor 是否已经在前面过滤过是否匹配 Pointcut (极少用到)void setPreFiltered(boolean preFiltered);// 获取 Advisor 是否已经在前面过滤过是否匹配 Pointcut (极少用到)boolean isPreFiltered();// 获取所有的 AdvisorAdvisor[] getAdvisors();// 增加 Advisor 到链表的最后void addAdvisor(Advisor advisor) throws AopConfigException;// 在指定位置增加 Advisorvoid addAdvisor(int pos, Advisor advisor) throws AopConfigException;// 删除指定的 Advisorboolean removeAdvisor(Advisor advisor);// 删除指定位置的 Advisorvoid removeAdvisor(int index) throws AopConfigException;// 返回 Advisor 所在位置de indexint indexOf(Advisor advisor);// 将指定的两个 Advisor 进行替换boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;// 增加 Advice <- 这个Advice将会包裹成 DefaultPointcutAdvisorvoid addAdvice(Advice advice) throws AopConfigException;// 在指定 index 增加 Advice <- 这个Advice将会包裹成 DefaultPointcutAdvisorvoid addAdvice(int pos, Advice advice) throws AopConfigException;// 删除给定的 Adviceboolean removeAdvice(Advice advice);// 获取 Advice 的索引位置int indexOf(Advice advice);// 将 ProxyConfig 通过 String 形式返回String toProxyConfigString();
}

它的主要实现,就是面向我们创建代理的,非常实用:

  1. ProxyFactory: 这个类通过构造函数中的 proxyInterface/interceptor/targetSource 来创建代理对象(这个类是编程式 AOP 中最常用的对象)
  2. ProxyFactoryBean: 这个类是基于 FactoryBean 的 Proxy创建形式, 其通过代理的 Interface, targetSource 与指定的 interceptorNames 来创建对应的AopProxy, 最后生成对应的代理对象
  3. AspectJProxyFactory: 将一个被 @Aspect 注解标示的类丢入其中, 变创建了对应的代理对象 (这个类现在已经很少用了。 但是@Aspect方式常用哦)

5、TargetSource

TargetSource:其实是动态代理作用的对象

  1. HotSwappableTargetSource: 进行线程安全的热切换到对另外一个对象实施动态代理操作
  2. AbstractPoolingTargetSource: 每次进行生成动态代理对象时都返回一个新的对象(比如内部实现类CommonsPool2TargetSource就是例子,但它依赖于common-pool2包)
  3. ThreadLocalTargetSource: 为每个进行请求的线程维护一个对象的 TargetSource
  4. SingletonTargetSource: 最普遍最基本的单例 TargetSource, 在 Spring 中生成动态代理对象, 一般都是用这个 TargetSource

6、AdvisorChainFactory

这个接口主要定义了从 Advised中获取 Advisor 并判断其是否与 对应的 Method 相匹配, 最终返回的是MethodInterceptor。(其中对 Advisor 转化成 MethodInterceptor 的工作都是交由 DefaultAdvisorAdapterRegistry 来完成, ) 它的实现类为:DefaultAdvisorChainFactory,提供的唯一方法是:

// 获取匹配 targetClass 与 method 的所有切面的通知
@Override
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);                                  // PS: 这里 config.getAdvisors 获取的是 advisors 是数组Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);                                       // 判断是有 IntroductionAdvisor 匹配到// 下面这个适配器将通知 [Advice] 包装成拦截器 [MethodInterceptor]; 而 DefaultAdvisorAdapterRegistry则是适配器的默认实现AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();for (Advisor advisor : config.getAdvisors()) {              // 获取所有的 Advisorif (advisor instanceof PointcutAdvisor) {               // advisor 是 PointcutAdvisor 的子类// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;// 判断此切面 [advisor] 是否匹配 targetClass (PS: 这里是类级别的匹配)if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {/** 通过对适配器将通知 [Advice] 包装成 MethodInterceptor, 这里为什么是个数组? 因为一个通知类*  可能同时实现了前置通知[MethodBeforeAdvice], 后置通知[AfterReturingAdvice], 异常通知接口[ThrowsAdvice]*   环绕通知 [MethodInterceptor], 这里会将每个通知统一包装成 MethodInterceptor*/MethodInterceptor[] interceptors = registry.getInterceptors(advisor);MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();// 是否匹配 targetClass 类的 method 方法     (PS: 这里是方法级别的匹配)if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {if (mm.isRuntime()) {                       // 看了对应的所有实现类, 只有 ControlFlowPointcut 与 AspectJExpressionPointcut 有可能 返回 true// 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));           // 里面装的是 Advise 与 MethodMatcher}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {  // 这里是 IntroductionAdvisor// 如果是引入切面的话则判断它是否适用于目标类, Spring 中默认的引入切面实现是 DefaultIntroductionAdvisor 类// 默认的引入通知是 DelegatingIntroductionInterceptor 它实现了 MethodInterceptor 接口sIntroductionAdvisor 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;
}

7、DefaultAdvisorAdapterRegistry

这里类里面存在着 MethodBeforeAdviceAdapter, AfterReturningAdviceAdapter, ThrowsAdviceAdapter 这三个类是将 Advice适配成MethodInterceptor的适配类; 而其本身具有两个重要的功能:

1、将 Advice/MethodInterceptor 包裹成 DefaultPointcutAdvisor
2、通过上面的三个适配类将 Advisor 中的 Advice 适配成对应的MethodInterceptor
(PS: 在代理对象执行时, 执行的都是MethodInterceptor, 当然在进行配置时既可以配置 Advice, MethodInterceptor, Advisor均可)

8、AopProxyFactory

这个接口中定义了根据 AdvisedSupport 中配置的信息来生成合适的AopProxy (主要分为 基于Java 动态代理的 JdkDynamicAopProxy 与基于 Cglib 的ObjenesisCglibAopProxy)

9、MethodInvocation

MethodInvocation 是进行 invoke 对应方法 / MethodInterceptor的类。
其主要分成用于 Proxy 的 ReflectiveMethodInvocation, 与用于 Cglib 的 CglibMethodInvocation
(其实就是就是递归的调用 MethodInterceptor, 当没有 MethodInterceptor可以调用时)

10、AbstractAutoProxyCreator

这个类是声明式 Aop 编程中非常重要的一个角色:自动代理创建器
解读如下:

  1. AbstractAutoProxyCreator继承了 ProxyProcessorSupport, 所以它具有了ProxyConfig中动态代理应该具有的配置属性
  2. AbstractAutoProxyCreator 实现了 SmartInstantiationAwareBeanPostProcessor(包括实例化的前后置函数, 初始化的前后置函数) 并进行了实现
  3. 实现了 创建代理类的主方法 createProxy 方法
  4. 定义了抽象方法 getAdvicesAndAdvisorsForBean**(获取 Bean对应的 Advisor)**

AbstractAutoProxyCreator 中等于是构建了创建 Aop 对象的主逻辑**(模版)**,而其子类 AbstractAdvisorAutoProxyCreator 实现了getAdvicesAndAdvisorsForBean 方法, 并且通过工具类 BeanFactoryAdvisorRetrievalHelper(PS: 它的方法findAdvisorBeans中实现类获取容器中所有 Advisor 的方法) 来获取其对应的 Advisor。它的主要子类如下:

  1. AspectJAwareAdvisorAutoProxyCreator: 通过解析 aop 命名空间的配置信息时生成的 AdvisorAutoProxyCreator, 主要通过ConfigBeanDefinitionParser.parse() -> ConfigBeanDefinitionParser.configureAutoProxyCreator() -> AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary() -> AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(); 与之对应的 Pointcut 是AspectJExpressionPointcut, Advisor 是 AspectJPointcutAdvisor, Advice 则是 AspectJAfterAdvice, AspectJAfterReturningAdvice, AspectJAfterThrowingAdvice, AspectJAroundAdvice
  2. AnnotationAwareAspectJAutoProxyCreator: 这是基于 @AspectJ注解生成的 切面类的一个 AbstractAutoProxyCreator, 解析额工作交给了 AspectJAutoProxyBeanDefinitionParser, 步骤如下AspectJAutoProxyBeanDefinitionParser.parse() -> AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary() -> AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()
  3. DefaultAdvisorAutoProxyCreator: 这个类也是 AbstractAutoProxyCreator的子类, 它帅选作用的类时主要是根据其中的 advisorBeanNamePrefix(类名前缀)配置进行判断
  4. BeanNameAutoProxyCreator: 通过类的名字来判断是否作用(正则匹配)

上面这几个类主要是声明式 Aop 编程的主要功能类

总结

本篇主要介绍了 Spring-Aop 中的主要构建组件, 并进行相应的说明, 单纯的讲 aop 这个概念其实不复杂,,但在Spring这个产品中,就显得很复杂了。主要体现在如下方面:

  1. 涉及的组件多 -> Pointcut, Advice, MethodInterceptor, Advised, Advisor, TargetSource, AopProxyFactory, MethodInvocation, AbstractAutoProxyCreator, 这也造成掌握 Spring-aop 的难度
  2. 实现aop需要多个基础功能的支持(AspectJ中的注解及注解解析, Cglib, java中的 Proxy, Asm字节码(主要式解析方法中的参数名))
  3. 结合了 BeanPostProcessor 在Bean的实例化/初始化阶段就进行生成对应的代理类(比如 AspectJAwareAdvisorAutoProxyCreator与AnnotationAwareAspectJAutoProxyCreator)

总体而言,Spring AOP是众多技术的一个综合,若要要彻底了解和运用自如,相关的周边技术能力必不可少。因此我平时书说的,基础不牢,地动山摇,在这里的学习过程中会有所体会~~~


关注A哥

AuthorA哥(YourBatman)
个人站点www.yourbatman.cn
E-mailyourbatman@qq.com
微 信fsx641385712
活跃平台
公众号BAT的乌托邦(ID:BAT-utopia)
知识星球BAT的乌托邦
每日文章推荐每日文章推荐

BAT的乌托邦


http://chatgpt.dhexx.cn/article/Qr3tRYvk.shtml

相关文章

ADDA: Adversarial Discriminative Domain Adaptation

ADDA原理理解 ADDA中源域和目标域经过不同的映射来实现对齐。 ADDA的目标函数包括三项&#xff1a; 1.源域的分类误差项 2.域分类器的分类误差项 3.生成器在目标域的误差项 1.源域的分类误差项 源域数据在经过映射Ms后的分类误差最小&#xff1a; 2.域分类器的分类误差项 …

IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true'

在使用 Async 注解实现异步线程的时候&#xff0c;为了能够在同类中调用&#xff0c;使用AopContext获取类的实例&#xff0c;结果报错&#xff1a; 调用如下&#xff1a; GetMapping("test03")public void testAsync03() throws InterruptedException {log.info(&…

ADVISOR - 1

文章目录 1. ADVISOR 是什么1. 2 ADVISOR 可以用来做什么1.3 ADVISOR 不能做什么 1. ADVISOR 是什么 它是基于 MATLAB/Simulink 开发的一系列模型、数据以及脚本&#xff0c;能帮助我们快速分析传统车、纯电车以及混动车的性能和油耗。 能找到的最新的 ADVISOR 版本是 2003&a…

Advisor-Advisee Relationship

一、实习目的及要求 此次实习的任务中有Advisor-advisee Relationships (AARs)和通过分别计算AAR的概率而取得的共同作者关系。在数据中&#xff0c;用八个4位代码表示作者。 数据从合作双方的学术经历&#xff0c;合作经历的角度提取了特征。例如&#xff0c;如果已知A与B在…

ADV

悦谷首城 我司是专业的房产服务公司&#xff0c;主要从事北京拆迁安置房买卖中介、房屋租赁中介、代办房屋权证、房屋产权过户手续、垫资开发商房款&#xff0c;收拆迁房子指标&#xff0c;房产信息咨询等业务。公司经营上追求规模化、规范化、服务一体化。公司本着“诚信为本…

【Spring源码三千问】Advice、Advisor、Advised都是什么接口?

Advice、Advisor、Advised都是什么接口&#xff1f; 前言版本约定正文Advice、Advisor、Advised 类图AdviceMethodInterceptor AdvisorPointcutAdvisor AdvisedSpring AOP 代理类可以转换为 Advised 类型 小结 前言 在看 Spring AOP 的源码时&#xff0c;经常可以看到 Advice、…

【小家Spring】Spring AOP原理使用的基础类打点(AopInfrastructureBean、ProxyProcessorSupport、Advised、AjType)

每篇一句 没被洪水灌溉过&#xff0c;你怎么能证明这个城市的下水道架构师合理的呢&#xff1f; 相关阅读 【小家Spring】探索Spring AOP中aopalliance的Joinpoint、MethodInvocation、Interceptor、MethodInterceptor… 【小家Spring】Spring AOP原理使用的基础类打点&#x…

Spring AOP名词解释Advice,Pointcut,Advisor,Joinpoint,Advised是什么?

Advice advice解释为通知&#xff0c;需要执行的增强逻辑方法。 advice规范接口如图&#xff0c;分为了before&#xff0c;after等等&#xff0c;为什么没有around呢&#xff0c;因为是通过interceptor实现的。 这里可以看出&#xff0c;AfterAdvice最终会被转换包装成AfterR…

Advised,Advisor,Advice,Pointcut

2019独角兽企业重金招聘Python工程师标准>>> Advised->在Spring中创建了AOP代理之后&#xff0c;就能够使用org.springframework.aop.framework.Advised接口对它们进行管理。 任何AOP代理都能够被转型为这个接口&#xff0c;不论它实现了哪些其它接口 Advisor-&g…

Spring AOP编程官方文档解读之操作Advised对象

Spring AOP编程官方文档解读目录 文章目录 org.springframework.aop.framework.Advised是啥&#xff1f;看一下下面这个类结构图 可以看到无论是ProxyFactoryBean还是ProxyFactory最终都实现了这个接口、这个接口中的方法非常的多&#xff0c;我们随便看一下 public interfac…

arduino知识点梳理(二)——INPUT_PULLUP模式

参考文章1 参考文章2 arduino的引脚模式有三种&#xff1a; INPUT——输入模式OUTPUT——输出模式INPUT_PULLUP——输入上拉模式 Arduino 微控制器自带内部上拉电阻。如果需要使用内部上拉电阻&#xff0c;则应使用pinMode()将引脚设置为输入上拉&#xff08;INPUT_PULLUP&am…

Pull Up Field(字段上移)

两个子类拥有形同的字段 重构&#xff1a;将该字段移至超类

HAL库 output level 和 pull up/ pull down 的区别

从标准库过来的朋友可能对这两个选型有点分不清除 GPIO output level 即输出模式下初始化后端口的电位(高或低) GPIO Pull-up/Pull-down 即输入模式下的电位&#xff0c;例如按键检测

处理概括关系之一 :Pull Up Field(值域上移)

两个subclasses 拥有相同的值域。 将此一值域移至superclass。 动机&#xff08;Motivation&#xff09; 如果各个subclass 是分别开发的&#xff0c;或者是在重构过程中组合起来的&#xff0c;你常会发现它们拥有重复特性&#xff0c;特别是值域更容易重复。这样的值域有时拥有…

Push pull, open drain circuit, pull up, pull down resistor

Push pull 就以下面這個 電路來說&#xff0c; 因為沒有 pull up resistor&#xff0c; 所以 output voltage 由 low 往 high 的速度會較快。有兩個電晶體&#xff0c;一個on&#xff0c;一個 off&#xff0c; 可以 current sourcing&#xff0c;也可以 current sinking&#x…

上拉(Pull Up )或下拉(Pull Down)电阻详解

上拉&#xff08;Pull Up &#xff09;或下拉&#xff08;Pull Down&#xff09;电阻&#xff08;两者统称为“拉电阻”&#xff09;最基本的作用是&#xff1a;将状态不确定的信号线通过一个电阻将其箝位至高电平&#xff08;上拉&#xff09;或低电平&#xff08;下拉&#x…

BetterScroll 2.x 的 pulldown 使用、pullup使用

官方文档&#xff1a;https://better-scroll.github.io/docs/zh-CN/plugins/ BetterScrol滚动原理 有唯一的子节点子节点必须超出包裹的高度new BScroll&#xff08;‘容器名’&#xff09; html内容必须已经渲染完成 绿色部分为 wrapper&#xff0c;也就是父容器&#xff…

【超详细】output level 和 pull up/ pull down 的真正区别

目录 【超详细】output level 和 pull up/ pull down 的真正区别1. Output Level2. Pull up/ Pull down3. 两者的区别1&#xff09;对于Output口来说2&#xff09;而对于Input口来说 总结参考资料 【超详细】output level 和 pull up/ pull down 的真正区别 今天在使用stm32f1…

OUTPUT,INPUT,INPUT_PULLUP三种模式的区别

一&#xff0c;首先三种模式都需要由pinMode()函数来设置。 &#xff08;1&#xff09;设置引脚 为输出&#xff08;OUTPUT&#xff09;模式&#xff0c;此时引脚为低阻抗状态&#xff0c;可以向其他电路原件提供电流&#xff08;通常为40mA以内&#xff09; &#xff08;2&a…

Pull Up Method(函数上移)

动机 避免行为重复是很重要的。尽管重复的两个函数也可以各自工作得很好&#xff0c;但重复自身只会成为错误的滋生地&#xff0c;此外别无价值。无论何时&#xff0c;只要系统之内出现重复&#xff0c;你就会面临“修改其中一个却未能修改另一个”的风险。通常&#xff0c;找…