图解JAVA中Spring Aop作用

本文深入探讨了Spring框架下的AOP(面向切面编程)概念及其应用。解释了如何利用AOP减少代码耦合度,提高代码复用性,并详细介绍了五种通知类型:前置、后置、返回、异常及环绕通知。

这篇文章主要介绍了Java的Spring框架下的AOP的作用,需要的朋友可以参考


假如没有aop,在做日志处理的时候,我们会在每个方法中添加日志处理,比如

1

但大多数的日子处理代码是相同的,为了实现代码复用,我们可能把日志处理抽离成一个新的方法。但是这样我们仍然必须手动插入这些方法。

2

但这样两个方法就是强耦合的,假如此时我们不需要这个功能了,或者想换成其他功能,那么就必须一个个修改。

通过动态代理,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置

插入这些功能。这样的思想,被称为面向切面编程,亦即AOP。

3

为了在指定位置执行这些横向的功能,需要知道指定的是什么地方

4

例如上图,方法级别的aop实现,在一个程序执行链条中,把method2称为切点,也就是说在method2执行时会执行横切的功能,那么是在method2之前还是之后呢,又是执行什么呢?这些都由advice(通知)来指定。advice有5种类型,分别是

通知类型 简介

Before(前置通知) 目标方法调用之前执行

After(后置通知) 目标方法调用之后执行

After-returning(返回通知) 目标方法执行成功后执行

After-throwing(异常通知) 目标方法抛出异常后执行

Around(环绕通知) 相当于合并了前置和后置

把切点和通知合在一起就是切面了,一个切面指定了在何时何地执行何种方法。在spring aop中如此定义这个切面:



@Aspect
@Component
public  class  UserAspect {
@Before("execution(* com.aop.service.impl.UserServiceImpl.login(..))")
public void  loginLog(){
System.out.println("user login");
}
}

使用注解@Aspect将某个特定的类声明为切面,这样,该类下的方法就可以声明为横向的功能点后插入到指定位置。使用execution表达式声明在这个切点,格式如下

5

第一个位置指定了方法的返回值,*号代表任意类型的返回值,然后是所在的类和方法名,*号同样代表任意,就是该类中任意的方法,在上一个例子中方法名是login,则是指定了该类中的login方法。然后最后一个参数是方法入参,因为Java中支持重载,所以这个参数可以帮助你更精确的进行定位。两点表示任意参数类型。这样,execution表达式告诉了程序该在何地执行通知。而被诸如@Before注解修饰的方法就是通知的内容,也就是做什么。

至此,我们就可以使用spring aop,但是还有两点需要得到注意

将切面类声明为一个bean

切点指定的方法所在的类也同样需由spring注入才能生效

希望本篇文章对您有所帮助

### Spring AOP 面向切面编程详解与图解 Spring AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在通过分离横切关注点(cross-cutting concerns)来增强代码的模块化[^1]。AOP 的核心思想是将业务逻辑与系统服务(如日志记录、事务管理等)分离,从而提高代码的可维护性和复用性。 #### 核心概念 以下是 Spring AOP 中的核心概念及其解释: 1. **连接点(JoinPoint)** 连接点是指程序执行过程中的某个位置,例如方法调用或异常抛出。在 Spring AOP 中,连接点通常表示为方法的执行[^3]。 2. **切入点(Pointcut)** 切入点是一个描述符,用于匹配特定的连接点。它定义了哪些连接点需要应用通知。例如,可以定义一个切入点来匹配所有以 `save` 开头的方法[^3]。 3. **通知(Advice)** 通知是在特定连接点处执行的操作,即共性功能。Spring AOP 提供了五种类型的通知: - **Before Advice**:在方法执行前运行。 - **After Returning Advice**:在方法成功返回后运行。 - **After Throwing Advice**:在方法抛出异常时运行。 - **After (Finally) Advice**:无论方法是否抛出异常,都会运行。 - **Around Advice**:围绕方法执行,可以在方法前后运行自定义逻辑[^3]。 4. **切面(Aspect)** 切面是通知和切入点的结合体,描述了在哪执行什么操作。切面通常是通过注解或 XML 配置实现的[^3]。 5. **目标对象(Target Object)** 被代理的对象,即包含业务逻辑的类实例。 6. **代理对象(Proxy Object)** AOP 框架生成的对象,用于拦截对目标对象的方法调用,并在适当时候应用通知。 --- #### Spring AOP 实现方式 Spring AOP 支持两种主要的实现方式:基于注解和基于 XML 的配置。 1. **基于注解的实现** 使用 `@Aspect` 注解定义切面类,并使用以下注解定义通知: ```java @Before("execution(* com.example.service.*.*(..))") public void beforeAdvice() { System.out.println("Before advice executed"); } ``` 2. **基于 XML 的实现** 在 XML 配置文件中定义切面和通知。以下是一个简单的示例: ```xml <aop:config> <aop:aspect id="logging" ref="loggingBean"> <aop:before method="beforeAdvice" pointcut="execution(* com.example.service.*.*(..))"/> </aop:aspect> </aop:config> ``` --- #### 图解 Spring AOP 工作流程 以下是 Spring AOP 的工作流程图解: ``` +-------------------+ | 客户端调用 | | 方法 | +-------------------+ | v +-------------------+ | 代理对象 | | (拦截方法调用)| +-------------------+ | v +-------------------+ | 应用通知 | | (Before/After)| +-------------------+ | v +-------------------+ | 目标对象方法 | | 执行业务逻辑 | +-------------------+ ``` - **客户端调用方法**:应用程序发起对目标对象方法的调用。 - **代理对象拦截**:代理对象捕获方法调用并决定是否应用通知。 - **应用通知**:根据切入点规则,执行相应的通知逻辑。 - **目标对象执行**:最终调用目标对象的方法以完成业务逻辑。 --- #### Spring AOP 与 AspectJ 对比 | 特性 | Spring AOP | AspectJ | |------------------|------------------------------------|----------------------------------| | 实现方式 | 运行时动态代理 | 编译时/类加载时织入 | | 性能 | 较慢(代理调用) | 接近原生性能 | | 连接点支持 | 仅方法级别 | 字段、构造器、静态初始化块等 | | 织入时机 | 运行时 | 编译期或类加载期 | | 依赖 | 轻量(仅需 Spring) | 需要 AspectJ 编译器或 LTW | | 适用场景 | 简单切面(事务、日志等) | 复杂切面(性能监控等) | --- ### 示例代码 以下是一个基于注解的 Spring AOP 示例: ```java // 定义切面类 @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Method " + joinPoint.getSignature().getName() + " is called."); } @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result") public void logAfterReturning(Object result) { System.out.println("Method returned with result: " + result); } } ``` ```java // 目标类 @Service public class MyService { public String performTask() { return "Task completed"; } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值