From f9b1f6d0b8749610240c75d7ba78e03014661afe Mon Sep 17 00:00:00 2001 From: linlei Date: Tue, 7 May 2024 10:40:01 +0800 Subject: [PATCH] =?UTF-8?q?AspectInstanceFactory=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++-- .../README.md | 63 ++++++++--------- .../README.md | 51 +++++++------- .../main/java/com/xcs/spring/MyAspect.java | 4 +- .../main/java/com/xcs/spring/MyService.java | 4 +- .../README.md | 67 ++++++++++++------- 6 files changed, 109 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 5a13204..46c0de0 100644 --- a/README.md +++ b/README.md @@ -221,19 +221,24 @@ :启用AspectJ切面自动代理。 - [AnnotationAwareAspectJAutoProxyCreator](spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/README.md) :创建AOP代理以应用AspectJ风格的切面。 + - [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md) + :帮助检索并管理Spring AOP 中的 Advisor + Beans。 - [BeanFactoryAspectJAdvisorsBuilder](spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md) :构建@AspectJ注解切面,生成Spring AOP Advisors。 - - [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md):帮助检索并管理 - Spring AOP 中的 Advisor Beans。 + - [AspectInstanceFactory](spring-aop/spring-aop-aspectInstanceFactory/README.md) + :创建切面实例,支持多种实现方式。 + - [MetadataAwareAspectInstanceFactory](spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md) + :管理切面实例和元数据,支持多种实例化策略。 + - [AspectJAdvisorFactory](spring-aop/spring-aop-aspectJAdvisorFactory/README.md) + :创建AspectJ通知器实例,管理切面通知的创建和配置。 - [TargetSource](spring-aop/spring-aop-targetSource/README.md):管理AOP代理对象的获取与释放。 - [TargetSourceCreator](spring-aop/spring-aop-targetSourceCreator/README.md):创建特殊的目标源,定制代理对象的创建和管理。 - - [@EnableLoadTimeWeaving](spring-aop/spring-aop-enableLoadTimeWeaving/README.md):启用Spring加载时编织。 - - [AspectInstanceFactory](spring-aop/spring-aop-aspectInstanceFactory/README.md):创建切面实例,支持多种实现方式。 - - [MetadataAwareAspectInstanceFactory](spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md):管理切面实例和元数据,支持多种实例化策略。 - - [AspectJAdvisorFactory](spring-aop/spring-aop-aspectJAdvisorFactory/README.md):创建AspectJ通知器实例,管理切面通知的创建和配置。 - [AopContext](spring-aop/spring-aop-aopContext/README.md):获取Spring AOP代理对象的工具。 - [ExposeInvocationInterceptor](spring-aop/spring-aop-exposeInvocationInterceptor/README.md):暴露Spring AOP方法调用上下文的拦截器。 + - [@EnableLoadTimeWeaving](spring-aop/spring-aop-enableLoadTimeWeaving/README.md) + :启用Spring加载时编织。 + Spring AOT diff --git a/spring-aop/spring-aop-aspectInstanceFactory/README.md b/spring-aop/spring-aop-aspectInstanceFactory/README.md index 718a46e..0f9ec78 100644 --- a/spring-aop/spring-aop-aspectInstanceFactory/README.md +++ b/spring-aop/spring-aop-aspectInstanceFactory/README.md @@ -6,12 +6,9 @@ - [三、主要功能](#三主要功能) - [四、接口源码](#四接口源码) - [五、主要实现](#五主要实现) - - [六、最佳实践](#六最佳实践) - - [七、源码分析](#七源码分析) - - [SimpleAspectInstanceFactory](#simpleaspectinstancefactory) - - [SingletonAspectInstanceFactory](#singletonaspectinstancefactory) - - [SimpleBeanFactoryAwareAspectInstanceFactory](#simplebeanfactoryawareaspectinstancefactory) - - [八、常见问题](#八常见问题) + - [六、类关系图](#六类关系图) + - [七、最佳实践](#七最佳实践) + - [八、源码分析](#八源码分析) ### 一、基本信息 @@ -80,14 +77,32 @@ public interface AspectInstanceFactory extends Ordered { + 一个简单的切面实例工厂,用于创建基于注解的切面实例。 2. **SingletonAspectInstanceFactory** - + 一个单例的切面实例工厂,用于创建单例的切面实例。 3. **SimpleBeanFactoryAwareAspectInstanceFactory** - + 一个简单的 Bean 工厂感知切面实例工厂,用于在创建切面实例时考虑 Bean 工厂的上下文信息。 ++ 一个简单的 Bean 工厂感知切面实例工厂,用于在创建切面实例时考虑 Bean 工厂的上下文信息。 -### 六、最佳实践 +### 六、类关系图 + +~~~mermaid +classDiagram +direction BT +class AspectInstanceFactory { +<> + +} +class SimpleAspectInstanceFactory +class SimpleBeanFactoryAwareAspectInstanceFactory +class SingletonAspectInstanceFactory + +SimpleAspectInstanceFactory ..> AspectInstanceFactory +SimpleBeanFactoryAwareAspectInstanceFactory ..> AspectInstanceFactory +SingletonAspectInstanceFactory ..> AspectInstanceFactory + +~~~ + +### 七、最佳实践 使用不同类型的 `AspectInstanceFactory` 实现类来创建和管理切面实例。首先,通过 `SimpleAspectInstanceFactory` 和 `SingletonAspectInstanceFactory` 分别创建简单实例和单例实例的切面。然后,通过注册一个名为 "myAspect" 的单例 bean,并将其用于配置 `SimpleBeanFactoryAwareAspectInstanceFactory`,从而创建一个依赖于 Bean 工厂的切面实例。最后,展示了获取 `SimpleBeanFactoryAwareAspectInstanceFactory` 实例的切面对象,并输出其结果。 @@ -136,9 +151,9 @@ SimpleBeanFactoryAwareAspectInstanceFactory (1): com.xcs.spring.MyAspect@41ee392 SimpleBeanFactoryAwareAspectInstanceFactory (2): com.xcs.spring.MyAspect@41ee392b ``` -### 七、源码分析 +### 八、源码分析 -#### SimpleAspectInstanceFactory +**SimpleAspectInstanceFactory** `SimpleAspectInstanceFactory`类是 `AspectInstanceFactory` 接口的实现。每次调用 `getAspectInstance()` 方法创建指定切面类的新实例。它通过反射机制在运行时实例化切面类,并提供了方法来获取切面类、获取切面类的类加载器以及确定切面实例的顺序。 @@ -217,7 +232,7 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory { } ``` -#### SingletonAspectInstanceFactory +**SingletonAspectInstanceFactory** `SingletonAspectInstanceFactory` 类是 `AspectInstanceFactory` 接口的实现。该类通过指定的单例对象作为后端支持,每次调用 `getAspectInstance()` 方法时都返回相同的实例。此外,它还提供了方法来获取切面实例的类加载器以及确定切面实例的顺序,支持实现了 `Ordered` 接口的切面实例。 @@ -291,7 +306,7 @@ public class SingletonAspectInstanceFactory implements AspectInstanceFactory, Se } ``` -#### SimpleBeanFactoryAwareAspectInstanceFactory +**SimpleBeanFactoryAwareAspectInstanceFactory** `SimpleBeanFactoryAwareAspectInstanceFactory` 类是 `AspectInstanceFactory` 接口的实现。该类通过配置的 bean 名称从 `BeanFactory` 中定位切面实例。每次调用 `getAspectInstance()` 方法时,都会查找并返回指定名称的 bean。此外,它还提供了方法来获取切面实例的类加载器以及确定切面实例的顺序,支持实现了 `Ordered` 接口的切面实例。 @@ -362,25 +377,3 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan } } ``` - -### 八、常见问题 - -1. **切面实例化方式** - - + 如何创建切面实例?不同的实现类可能采用不同的实例化方式,比如单例、原型等。 - -2. **切面对象生命周期** - - + 切面实例是单例还是多例?在 Spring AOP 中,切面对象通常是单例的,但也可以是原型的,这可能会影响到切面对象的状态管理和线程安全性。 - -3. **切面对象获取方式** - - + 切面对象是如何被获取的?有些实现类可能通过配置文件指定 bean 名称,然后从 `BeanFactory` 中获取,而另一些可能直接实例化切面对象。 - -4. **切面对象依赖注入** - - + 切面对象是否可以依赖注入其他 Spring 管理的 bean?如果是,如何实现依赖注入? - -5. **切面对象的顺序** - - + 如果多个切面对象同时存在,它们的执行顺序是如何确定的?是否可以通过实现 `Ordered` 接口或其他方式指定切面对象的执行顺序? \ No newline at end of file diff --git a/spring-aop/spring-aop-aspectJAdvisorFactory/README.md b/spring-aop/spring-aop-aspectJAdvisorFactory/README.md index 1a52a7b..2709687 100644 --- a/spring-aop/spring-aop-aspectJAdvisorFactory/README.md +++ b/spring-aop/spring-aop-aspectJAdvisorFactory/README.md @@ -1,14 +1,14 @@ ## AspectJAdvisorFactory -- [AspectJAdvisorFactory](#AspectJAdvisorFactory) +- [AspectJAdvisorFactory](#aspectjadvisorfactory) - [一、基本信息](#一基本信息) - [二、基本描述](#二基本描述) - [三、主要功能](#三主要功能) - [四、接口源码](#四接口源码) - [五、主要实现](#五主要实现) - - [六、最佳实践](#六最佳实践) - - [七、源码分析](#七源码分析) - - [八、常见问题](#八常见问题) + - [六、类关系图](#六类关系图) + - [七、最佳实践](#七最佳实践) + - [八、源码分析](#八源码分析) ### 一、基本信息 @@ -117,7 +117,24 @@ public interface AspectJAdvisorFactory { + `ReflectiveAspectJAdvisorFactory` 实现类是利用反射机制解析 AspectJ 注解,并创建相应的 Advisor 对象,支持注解风格的 AspectJ 切面,为我们提供了灵活而强大的面向切面编程能力。 -### 六、最佳实践 +### 六、类关系图 + +~~~mermaid +classDiagram +direction BT +class AbstractAspectJAdvisorFactory +class AspectJAdvisorFactory { +<> + +} +class ReflectiveAspectJAdvisorFactory + +AbstractAspectJAdvisorFactory ..> AspectJAdvisorFactory +ReflectiveAspectJAdvisorFactory --> AbstractAspectJAdvisorFactory + +~~~ + +### 七、最佳实践 使用 `AspectJAdvisorFactory` 实现类 `ReflectiveAspectJAdvisorFactory`,以创建 Advisors 并打印它们。首先,通过 `DefaultListableBeanFactory` 创建了一个默认的 Bean 工厂,并在其中注册了一个名为 "myAspect" 的单例 Bean,类型为 `MyAspect`。然后,创建了一个 `MetadataAwareAspectInstanceFactory` 实例 `factory`,用于实例化切面。接着,创建了 `ReflectiveAspectJAdvisorFactory` 实例 `aspectJAdvisorFactory`,并使用它获取所有注解式 AspectJ 方法的 Advisors。最后,通过遍历 Advisors 并打印的方式展示了这些 Advisors。 @@ -177,7 +194,7 @@ InstantiationModelAwarePointcutAdvisor: expression [execution(* com.xcs.spring.M InstantiationModelAwarePointcutAdvisor: expression [execution(* com.xcs.spring.MyService.doSomething(..))]; advice method [public void com.xcs.spring.MyAspect.after()]; perClauseKind=SINGLETON ``` -### 七、源码分析 +### 八、源码分析 在`org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors`方法中,根据给定的切面实例工厂,获取切面类中的通知器列表。首先,验证切面类的有效性,然后使用元数据判断是否需要延迟实例化切面实例工厂。接着,遍历切面类中的方法,获取通知器,并将其添加到通知器列表中。如果切面是针对目标的并且是延迟实例化的,则添加一个虚拟实例化通知器。最后,查找切面类中的引入字段,获取相应的通知器,并将其添加到通知器列表中,最终返回该列表。 @@ -489,25 +506,3 @@ public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut return springAdvice; } ``` - -### 八、常见问题 - -1. **切点表达式问题** - - + 关于如何编写有效的切点表达式,以及如何在表达式中使用 AspectJ 的语法和通配符。 - -2. **通知类型问题** - - + 关于不同类型的通知(Before、After、Around 等)的使用场景和区别,以及如何在 AspectJ 注解中正确声明和使用它们。 - -3. **参数绑定问题** - - + 关于如何在通知方法中获取和使用方法参数,以及如何在切点表达式中指定参数名称。 - -4. **Introduction(引入)问题** - - + 关于如何在切面中引入新的接口或功能,以及如何正确配置和使用 Introduction 相关的注解和通知。 - -5. **Spring AOP 与 AspectJ 的区别问题** - - + 关于 Spring AOP 和 AspectJ 在实现方式、功能特性和应用场景上的区别,以及何时选择使用哪种方式。 \ No newline at end of file diff --git a/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java b/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java index 4c37fd5..62b2044 100644 --- a/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java +++ b/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyAspect.java @@ -7,12 +7,12 @@ import org.aspectj.lang.annotation.Before; @Aspect class MyAspect { - @Before("execution(* com.xcs.spring.MyService.doSomething(..))") + @Before("execution(* com.xcs.spring.MyService.foo(..))") public void before() { System.out.println("Before executing the method..." ); } - @After("execution(* com.xcs.spring.MyService.doSomething(..))") + @After("execution(* com.xcs.spring.MyService.foo(..))") public void after() { System.out.println("After executing the method..." ); } diff --git a/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java b/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java index 843fa2c..128f345 100644 --- a/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java +++ b/spring-aop/spring-aop-aspectJAdvisorFactory/src/main/java/com/xcs/spring/MyService.java @@ -1,7 +1,7 @@ package com.xcs.spring; public class MyService { - public void doSomething() { - System.out.println("Doing something..."); + public void foo() { + System.out.println("foo..."); } } diff --git a/spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md b/spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md index eb25073..391e394 100644 --- a/spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md +++ b/spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md @@ -1,18 +1,14 @@ ## MetadataAwareAspectInstanceFactory + - [MetadataAwareAspectInstanceFactory](#metadataawareaspectinstancefactory) - [一、基本信息](#一基本信息) - [二、基本描述](#二基本描述) - [三、主要功能](#三主要功能) - [四、接口源码](#四接口源码) - [五、主要实现](#五主要实现) - - [六、最佳实践](#六最佳实践) - - [七、源码分析](#七源码分析) - - [SimpleMetadataAwareAspectInstanceFactory](#simplemetadataawareaspectinstancefactory) - - [SingletonMetadataAwareAspectInstanceFactory](#singletonmetadataawareaspectinstancefactory) - - [BeanFactoryAspectInstanceFactory](#beanfactoryaspectinstancefactory) - - [LazySingletonAspectInstanceFactoryDecorator](#lazysingletonaspectinstancefactorydecorator) - - [八、常见问题](#八常见问题) - + - [六、类关系图](#六类关系图) + - [七、最佳实践](#七最佳实践) + - [八、源码分析](#八源码分析) ### 一、基本信息 @@ -93,7 +89,40 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor - 这个实现类是一个装饰器,用于延迟初始化单例的切面实例。它在首次请求切面实例时才进行实例化,以提高性能并延迟资源消耗。 -### 六、最佳实践 +### 六、类关系图 + +~~~mermaid +classDiagram +direction BT +class AspectInstanceFactory { +<> + +} +class BeanFactoryAspectInstanceFactory +class LazySingletonAspectInstanceFactoryDecorator +class MetadataAwareAspectInstanceFactory { +<> + +} +class PrototypeAspectInstanceFactory +class SimpleAspectInstanceFactory +class SimpleMetadataAwareAspectInstanceFactory +class SingletonAspectInstanceFactory +class SingletonMetadataAwareAspectInstanceFactory + +BeanFactoryAspectInstanceFactory ..> MetadataAwareAspectInstanceFactory +LazySingletonAspectInstanceFactoryDecorator ..> MetadataAwareAspectInstanceFactory +MetadataAwareAspectInstanceFactory --> AspectInstanceFactory +PrototypeAspectInstanceFactory --> BeanFactoryAspectInstanceFactory +SimpleAspectInstanceFactory ..> AspectInstanceFactory +SimpleMetadataAwareAspectInstanceFactory ..> MetadataAwareAspectInstanceFactory +SimpleMetadataAwareAspectInstanceFactory --> SimpleAspectInstanceFactory +SingletonAspectInstanceFactory ..> AspectInstanceFactory +SingletonMetadataAwareAspectInstanceFactory ..> MetadataAwareAspectInstanceFactory +SingletonMetadataAwareAspectInstanceFactory --> SingletonAspectInstanceFactory +~~~ + +### 七、最佳实践 使用不同的 `MetadataAwareAspectInstanceFactory` 实现类来实例化切面,并展示了它们的不同行为。首先,使用 `SimpleMetadataAwareAspectInstanceFactory` 和 `SingletonMetadataAwareAspectInstanceFactory` 分别创建单例的切面实例,然后使用 `BeanFactoryAspectInstanceFactory` 在 Spring Bean 工厂中注册并实例化切面,最后使用 `LazySingletonAspectInstanceFactoryDecorator` 延迟初始化单例切面实例。在每个步骤中,都输出了切面实例及其元数据信息。 @@ -156,9 +185,9 @@ LazySingletonAspectInstanceFactoryDecorator AspectCreationMutex = null LazySingletonAspectInstanceFactoryDecorator AspectMetadata = {"aspectName":"myAspect","aspectClass":"com.xcs.spring.MyAspect","perClausePointcut":{}} ``` -### 七、源码分析 +### 八、源码分析 -#### SimpleMetadataAwareAspectInstanceFactory +**SimpleMetadataAwareAspectInstanceFactory** `SimpleMetadataAwareAspectInstanceFactory` 是一个实现了 `MetadataAwareAspectInstanceFactory` 接口的类,它在每次调用 `getAspectInstance()` 方法时都会为指定的切面类创建一个新的实例。这个类通过 `AspectMetadata` 对象来管理切面的元数据信息,并且实现了 `getAspectMetadata()` 方法来提供这些元数据。它还实现了 `getAspectCreationMutex()` 方法来返回切面实例的创建锁,以及 `getOrderForAspectClass()` 方法来确定切面类的顺序。 @@ -219,7 +248,7 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan } ``` -#### SingletonMetadataAwareAspectInstanceFactory +**SingletonMetadataAwareAspectInstanceFactory** `SingletonMetadataAwareAspectInstanceFactory` 是一个实现了 `MetadataAwareAspectInstanceFactory` 接口的类,它通过指定的单例对象支持切面实例的创建,每次调用 `getAspectInstance()` 方法都返回相同的实例。该类使用一个单例的切面实例,并通过 `AspectMetadata` 对象管理切面的元数据信息。它也实现了 `Serializable` 接口以支持序列化,并且继承自 `SingletonAspectInstanceFactory`,提供了获取切面实例的相关方法和逻辑。 @@ -284,7 +313,7 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect } ``` -#### BeanFactoryAspectInstanceFactory +**BeanFactoryAspectInstanceFactory** `BeanFactoryAspectInstanceFactory` 是一个实现了 `MetadataAwareAspectInstanceFactory` 接口的类,它通过 Spring 的 `BeanFactory` 支持切面实例的创建。这个工厂可以通过指定的 bean 名称从 `BeanFactory` 中获取切面实例,并且可以通过提供的类型来自省以创建 AspectJ 的元数据信息。它可以处理单例和非单例的情况,并且能够确定切面的顺序,支持使用 `Ordered` 接口或 `@Order` 注解来定义顺序。 @@ -420,7 +449,7 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst } ``` -#### LazySingletonAspectInstanceFactoryDecorator +**LazySingletonAspectInstanceFactoryDecorator** `LazySingletonAspectInstanceFactoryDecorator`类是一个装饰器,用于确保一个 `MetadataAwareAspectInstanceFactory` 只实例化一次。它包装了另一个 `MetadataAwareAspectInstanceFactory` 实例,并在首次调用 `getAspectInstance()` 方法时进行实例化。在后续的调用中,它将返回已经实例化的对象,而不会再次实例化。 @@ -525,13 +554,3 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar } ``` - -### 八、常见问题 - -1. **切面实例化策略** - - + 我们需要了解不同实现类的切面实例化策略,例如单例模式、原型模式等,以便选择适合应用场景的实现类。 - -2. **AOP配置错误** - - + 在使用 `MetadataAwareAspectInstanceFactory` 实现时,可能会出现AOP配置错误导致切面无法正确实例化的问题,需要仔细检查配置并进行调试。 \ No newline at end of file