首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
AOP引入:OOP存在哪些局限性?
AOP常见使用场景
AOP概念:Aspect、Join Point和Advice等术语应该如何理解?
Java AOP设计模式:代理、判断和拦截器模式
Java AOP代理模式(Proxy):Java静态代理和动态代理的区别是什么?
Java AOP判断模式(Predicate):如何筛选Join Point?
Java AOP拦截器模式(Interceptor):拦截执行分别代表什么?
Spring AOP 功能概述:核心特性、编程模型和使用限制
Spring AOP编程模型:注解驱动、XML配置驱动和底层API
Spring AOP设计目标:Spring AOP与 AOP框架之间的关系是竞争还是互补?
Spring AOP Advice类型:Spring AOP丰富了哪些AOP Advice呢?
Spring AOP代理实现:为什么Spring Framework选择三种不同AOP实现?
JDK动态代理:为什么Proxy.newProxyInstance会生成新的字节码?
CGLIB动态代理:为什么Java动态代理无法满足AOP的需要?
AspectJ代理代理:为什么Spring推荐AspectJ注解?
AspectJ基础:Aspect、Join Points、Pointcuts和Advice语法和特性
AspectJ注解驱动:注解能完全替代AspectJ语言吗?
Spring核心基础:《小马哥讲Spring核心编程思想》还记得多少?
@AspectJ注解驱动
编程方式创建 @AspectJ代理
XML配置驱动 - 创建AOP代理
标准代理工厂API - ProxyFactory
@AspectJ Pointcut指令与表达式:为什么Spring只能有限支持?
XML配置Pointcut
API实现Pointcut
@AspectJ拦截动作:@Around与@Pointcut有区别吗?
XML配置Around Advice
API实现Around Advice
@AspectJ前置动作:@Before与@Around谁优先级执行?
XML配置Before Advice
API实现Before Advice
@AspectJ后置动作 - 三种After Advice之间的关系?
XML配置三种After Advice
API实现三种After Advice
自动动态代理
替换TargetSource
Spring AOP API整体设计
接入点接口 - Joinpoint
Joinpoint条件接口 - Pointcut
Pointcut操作 - ComposablePointcut
Pointcut便利实现
Pointcut AspectJ实现 - AspectJExpressionPointcut
Joinpoint执行动作接口 - Advice
Joinpoint Before Advice标准实现
Joinpoint Before Advice AspectJ实现
Joinpoint After Advice标准实现
Joinpoint After Advice AspectJ实现
Advice容器接口 - Advisor
Pointcut与Advice连接器 - PointcutAdvisor
Introduction与Advice连接器 - IntroductionAdvisor
Advisor的Interceptor适配器 - AdvisorAdapter
AdvisorAdapter实现
AOP代理接口 - AopProxy
AopProxy工厂接口与实现
JDK AopProxy实现 - JdkDynamicAopProxy
当前位置:
首页>>
技术小册>>
Spring AOP 编程思想(上)
小册名称:Spring AOP 编程思想(上)
### 替换TargetSource:深入理解与实战 在Spring AOP(面向切面编程)的广阔领域中,`TargetSource`是一个核心概念,它扮演着连接代理对象与目标对象之间的桥梁角色。理解并灵活替换`TargetSource`是实现高级AOP配置、动态目标选择、以及集成复杂依赖管理策略的关键。本章将深入探讨`TargetSource`的工作原理、常见实现方式以及如何通过自定义`TargetSource`来替换默认行为,以满足特定的业务或架构需求。 #### 一、`TargetSource`基础概览 `TargetSource`是Spring AOP框架中用于封装和管理目标对象(即被代理对象)的接口。在AOP代理的创建过程中,`ProxyFactory`或`AdvisedSupport`等核心类通过`TargetSource`获取目标对象实例,进而生成代理对象。这种设计允许Spring在代理对象与目标对象之间插入额外的行为(即切面),同时保持对目标对象管理的灵活性。 `TargetSource`接口定义了两个核心方法: - `getTarget()`:返回当前管理的目标对象实例。 - `releaseTarget(Object target)`:当不再需要目标对象时(如代理对象被销毁时),可选地释放目标对象资源。此方法的具体实现依赖于`TargetSource`的具体类型。 #### 二、常见`TargetSource`实现 Spring提供了几种内置的`TargetSource`实现,每种实现都针对特定的场景进行了优化: 1. **SingletonTargetSource**:这是最简单的`TargetSource`实现,它管理一个单例目标对象。所有通过该`TargetSource`获取的目标对象实例都是同一个。 2. **PrototypeTargetSource**:与`SingletonTargetSource`相反,`PrototypeTargetSource`每次调用`getTarget()`时都会创建一个新的目标对象实例。这对于需要独立状态的目标对象非常有用。 3. **HotSwappableTargetSource**:允许在运行时动态替换目标对象,无需重新创建代理对象。这在需要热插拔功能的应用中特别有用,如在不重启应用的情况下更新业务逻辑。 4. **ThreadLocalTargetSource**:将目标对象实例与当前线程绑定,确保每个线程都有自己独立的目标对象实例。这在处理线程局部变量或需要线程隔离的场景中非常有用。 5. **PoolingTargetSource**:管理一个目标对象池,以复用目标对象实例。这有助于减少对象创建的开销,特别是在目标对象创建成本较高时。 #### 三、为什么需要替换`TargetSource` 尽管Spring提供了多种内置的`TargetSource`实现,但在实际应用中,我们可能会遇到需要更细粒度控制目标对象获取逻辑的场景。例如: - **动态选择目标对象**:根据运行时条件(如用户角色、请求参数等)动态选择不同的目标对象实例。 - **复杂依赖管理**:在目标对象创建过程中需要集成复杂的依赖注入逻辑,或目标对象本身需要动态配置。 - **集成第三方框架**:在Spring AOP中集成第三方框架时,可能需要自定义`TargetSource`来适配第三方框架的特定要求。 #### 四、自定义`TargetSource`的实现步骤 要实现自定义的`TargetSource`,你需要创建一个实现`TargetSource`接口的类。以下是一个简单的实现步骤: 1. **定义目标对象存储机制**:确定如何存储和获取目标对象。这可以是简单的单例模式、原型模式,也可以是更复杂的对象池或动态创建机制。 2. **实现`getTarget()`方法**:根据定义的存储机制,实现`getTarget()`方法以返回目标对象实例。这里可以加入任何必要的逻辑来动态选择或创建目标对象。 3. **(可选)实现`releaseTarget(Object target)`方法**:如果目标对象有特殊的释放逻辑(如资源清理、连接关闭等),则实现此方法。对于大多数情况,如果不需要特别处理,可以简单地留空或调用父类实现(如果继承自某个已实现的`TargetSource`类)。 4. **集成到Spring AOP配置中**:将自定义的`TargetSource`配置到Spring AOP的代理工厂或顾问(Advisor)中,以便在代理对象创建时使用。 #### 五、实战案例:动态目标对象选择 假设我们有一个基于角色的访问控制系统,不同用户角色需要访问不同的服务实现。我们可以创建一个自定义的`TargetSource`来实现这一需求: ```java public class RoleBasedTargetSource implements TargetSource { private Map<String, Object> targets = new HashMap<>(); public void addTarget(String role, Object target) { targets.put(role, target); } @Override public Object getTarget() throws Exception { // 假设有一个方法获取当前用户角色 String role = SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream() .map(GrantedAuthority::getAuthority) .findFirst() .orElse("DEFAULT"); return targets.getOrDefault(role, targets.get("DEFAULT")); } @Override public void releaseTarget(Object target) throws Exception { // 如果有必要,可以在这里实现资源释放逻辑 } // 其他必要的getter和setter } ``` 在这个例子中,我们根据当前用户的角色从`targets`映射中选择相应的目标对象。如果找不到特定角色的目标对象,则回退到默认目标对象。这种方式允许我们在不修改现有服务接口和实现的前提下,通过简单地添加新的目标对象到`RoleBasedTargetSource`中,来支持新的用户角色或服务变体。 #### 六、总结 通过替换`TargetSource`,我们可以实现更加灵活和强大的目标对象管理策略,满足复杂业务场景下的动态目标选择、依赖注入和集成需求。无论是利用Spring提供的内置`TargetSource`实现,还是创建自定义的`TargetSource`,关键在于理解其背后的原理和适用场景,以及如何在Spring AOP框架中恰当地集成和使用它们。希望本章内容能够帮助读者深入理解`TargetSource`的作用和用法,并在实际项目中灵活运用。
上一篇:
自动动态代理
下一篇:
Spring AOP API整体设计
该分类下的相关小册推荐:
Spring Cloud微服务项目实战
SpringBoot零基础到实战
Mybatis合辑4-Mybatis缓存机制
Java语言基础3-流程控制
手把手带你学习SpringBoot-零基础到实战
深入理解Java虚拟机
Java语言基础8-Java多线程
Java语言基础9-常用API和常见算法
Java语言基础4-数组详解
Java语言基础1-基础知识
Java语言基础7-Java中的异常
深入拆解 Java 虚拟机