Spring AOP配置文件方式入门教程详解
作者:学IT的周星星
spring aop是一个面向切面的编程,在自己第一遍学习的时候,感觉aop没有什么作用,但是真实接触下来,感觉spring aop还是很有用途的,这篇文章主要介绍了Spring AOP配置文件方式入门教程的相关资料,需要的朋友可以参考下
一、什么是 AOP?
在学习 Spring 时,我们常听到 AOP(面向切面编程)。
简单来说,AOP 就是:
在不改变原有业务代码的情况下,给程序“加点料”。
例如,我们在保存用户时,想额外加上:
打印日志;
记录操作时间;
发送短信;
或者进行事务控制。
这些跟业务无关的功能,统一抽取到一个“切面”里,通过 AOP 技术“织入”到业务方法中,就不用每次都手写一遍啦!
二、AOP 的相关术语(一定要理解这几个!)
| 术语 | 含义 | 举例 |
|---|---|---|
| Joinpoint(连接点) | 被拦截的方法 | save() 方法 |
| Pointcut(切入点) | 定义要拦截哪些方法 | 只拦截 save() 开头的方法 |
| Advice(通知/增强) | 要做的事情(增强逻辑) | 打印日志、事务控制 |
| Target(目标对象) | 被代理的业务类 | UserServiceImpl |
| Weaving(织入) | 把增强逻辑应用到目标对象的过程 | 运行时动态生成代理 |
| Proxy(代理对象) | 织入增强后产生的新对象 | 由 Spring 生成 |
| Aspect(切面) | 切入点 + 通知 的组合 | 我们自定义的切面类 |
三、Spring AOP 配置文件方式入门
下面通过一个简单的例子演示:
在执行 UserServiceImpl.save() 方法之前,打印一句“增强的方法执行了…”
创建 Maven 项目并添加依赖
<dependencies>
<!-- Spring 核心容器 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- 日志相关 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- AOP 相关依赖 -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
创建业务类
UserService.java
package com.qcbyjy.demo2;
public interface UserService {
void save();
}
UserServiceImpl.java
package com.qcbyjy.demo2;
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("业务层:保存用户...");
}
}
创建切面类(增强逻辑)
MyXmlAspect.java
package com.qcbyjy.demo2;
/**
* 自定义切面类 = 切入点(表达式) + 通知(增强代码)
*/
public class MyXmlAspect {
// 通知逻辑:增强方法
public void log() {
System.out.println("增强的方法执行了...");
}
// 环绕通知示例
public void aroundLog(org.aspectj.lang.ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前...");
pjp.proceed(); // 手动执行目标方法
System.out.println("环绕后...");
}
}
Spring 配置文件(applicationContext_demo2.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置业务类 -->
<bean id="userService" class="com.qcbyjy.demo2.UserServiceImpl"/>
<!-- 配置切面类 -->
<bean id="myXmlAspect" class="com.qcbyjy.demo2.MyXmlAspect"/>
<!-- 配置 AOP 增强 -->
<aop:config>
<aop:aspect ref="myXmlAspect">
<!-- 前置通知:目标方法执行前增强 -->
<aop:before method="log"
pointcut="execution(* com.qcbyjy.demo2.UserServiceImpl.save(..))"/>
</aop:aspect>
</aop:config>
</beans>
测试类
Demo2.java
package com.qcbyjy.test;
import com.qcbyjy.demo2.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_demo2.xml")
public class Demo2 {
@Autowired
private UserService userService;
@Test
public void run1() {
userService.save();
}
}
输出结果:
增强的方法执行了...
业务层:保存用户...
说明 AOP 生效啦 🎉
四、切入点表达式详解
AOP 的核心是 切入点表达式,用来告诉 Spring 哪些方法要被增强。
基本格式:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
示例说明:
| 表达式 | 含义 |
|---|---|
execution(public void com.qcbyjy.demo2.UserServiceImpl.save()) | 精确匹配 |
execution(* com.qcbyjy.*.*ServiceImpl.*(..)) | 模糊匹配所有 ServiceImpl 的任意方法 |
execution(* com.qcbyjy.demo2.*.save*(..)) | 匹配 demo2 包下所有以 save 开头的方法 |
通配符规则:
*代表任意(一个)内容..代表任意包或任意参数
例如:
<aop:before method="log"
pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))"/>
表示:增强所有以 save 开头的方法。
五、AOP 的五种通知类型
| 通知类型 | 执行时机 | XML 配置标签 |
|---|---|---|
| 前置通知 | 目标方法执行前 | <aop:before> |
| 后置通知 | 方法成功执行后 | <aop:after-returning> |
| 异常通知 | 方法抛出异常后 | <aop:after-throwing> |
| 最终通知 | 不管成功或失败都会执行 | <aop:after> |
| 环绕通知 | 方法执行前后都能增强(最灵活) | <aop:around> |
六、环绕通知示例
<aop:around method="aroundLog"
pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />
执行顺序:
环绕前...
增强的方法执行了...
业务层:保存用户...
环绕后...
总结
| 概念 | 功能 |
|---|---|
| AOP | 把公共功能(如日志、事务)从业务逻辑中分离出来 |
| 切面类(Aspect) | 定义要增强的逻辑 |
| 切入点(Pointcut) | 定义哪些方法会被增强 |
| 通知(Advice) | 什么时候增强(前置、后置、环绕等) |
| 代理对象(Proxy) | Spring 自动帮我们生成的“带增强”的对象 |
通过这套机制,Spring AOP 让你的代码更清爽、可维护性更高。
到此这篇关于Spring AOP配置文件方式入门教程的文章就介绍到这了,更多相关Spring AOP配置文件方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
