AspectInstanceFactory优化

master
linlei 2024-05-07 10:40:01 +08:00
parent 99249afe35
commit f9b1f6d0b8
6 changed files with 109 additions and 97 deletions

View File

@ -221,19 +221,24 @@
启用AspectJ切面自动代理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AnnotationAwareAspectJAutoProxyCreator](spring-aop/spring-aop-annotationAwareAspectJAutoProxyCreator/README.md)
创建AOP代理以应用AspectJ风格的切面。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
- [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md)
帮助检索并管理Spring AOP 中的 Advisor
Beans。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [BeanFactoryAspectJAdvisorsBuilder](spring-aop/spring-aop-beanFactoryAspectJAdvisorsBuilder/README.md)
:构建@AspectJ注解切面生成Spring AOP
Advisors。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [BeanFactoryAdvisorRetrievalHelper](spring-aop/spring-aop-beanFactoryAdvisorRetrievalHelper/README.md):帮助检索并管理
Spring AOP 中的 Advisor Beans。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AspectInstanceFactory](spring-aop/spring-aop-aspectInstanceFactory/README.md)
:创建切面实例,支持多种实现方式。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [MetadataAwareAspectInstanceFactory](spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md)
:管理切面实例和元数据,支持多种实例化策略。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AspectJAdvisorFactory](spring-aop/spring-aop-aspectJAdvisorFactory/README.md)
创建AspectJ通知器实例管理切面通知的创建和配置。<img src="https://img.shields.io/badge/Level-%E5%9B%B0%E9%9A%BE-%23FF3030"></img>
- [TargetSource](spring-aop/spring-aop-targetSource/README.md)管理AOP代理对象的获取与释放。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
- [TargetSourceCreator](spring-aop/spring-aop-targetSourceCreator/README.md):创建特殊的目标源,定制代理对象的创建和管理。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [@EnableLoadTimeWeaving](spring-aop/spring-aop-enableLoadTimeWeaving/README.md)启用Spring加载时编织。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AspectInstanceFactory](spring-aop/spring-aop-aspectInstanceFactory/README.md):创建切面实例,支持多种实现方式。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [MetadataAwareAspectInstanceFactory](spring-aop/spring-aop-metadataAwareAspectInstanceFactory/README.md):管理切面实例和元数据,支持多种实例化策略。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AspectJAdvisorFactory](spring-aop/spring-aop-aspectJAdvisorFactory/README.md)创建AspectJ通知器实例管理切面通知的创建和配置。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
- [AopContext](spring-aop/spring-aop-aopContext/README.md)获取Spring AOP代理对象的工具。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
- [ExposeInvocationInterceptor](spring-aop/spring-aop-exposeInvocationInterceptor/README.md)暴露Spring AOP方法调用上下文的拦截器。<img src="https://img.shields.io/badge/Level-%E7%AE%80%E5%8D%95-0099ff"></img>
- [@EnableLoadTimeWeaving](spring-aop/spring-aop-enableLoadTimeWeaving/README.md)
启用Spring加载时编织。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
+ Spring AOT

View File

@ -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 工厂的上下文信息。
### 六、最佳实践
### 六、类关系图
~~~mermaid
classDiagram
direction BT
class AspectInstanceFactory {
<<Interface>>
}
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` 接口或其他方式指定切面对象的执行顺序?

View File

@ -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 {
<<Interface>>
}
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 在实现方式、功能特性和应用场景上的区别,以及何时选择使用哪种方式。

View File

@ -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..." );
}

View File

@ -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...");
}
}

View File

@ -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 {
<<Interface>>
}
class BeanFactoryAspectInstanceFactory
class LazySingletonAspectInstanceFactoryDecorator
class MetadataAwareAspectInstanceFactory {
<<Interface>>
}
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配置错误导致切面无法正确实例化的问题需要仔细检查配置并进行调试。