Spring AOP配置文件方式入门教程详解

 更新时间:2025年11月10日 11:16:12   作者:学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配置文件方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于Spring整合mybatis注解扫描是否成功的问题

    基于Spring整合mybatis注解扫描是否成功的问题

    这篇文章主要介绍了Spring整合mybatis注解扫描是否成功的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java Lambda表达式和函数式接口实例分析

    Java Lambda表达式和函数式接口实例分析

    这篇文章主要介绍了Java Lambda表达式和函数式接口,结合实例形式分析了Java8 Lambda表达式和函数式接口相关原理、用法及操作注意事项,需要的朋友可以参考下
    2019-09-09
  • Spingboot JPA CriteriaBuilder 如何获取指定字段

    Spingboot JPA CriteriaBuilder 如何获取指定字段

    这篇文章 主要介绍了Spingboot JPA CriteriaBuilder 如何获取指定字段,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Netty中序列化的作用及自定义协议详解

    Netty中序列化的作用及自定义协议详解

    这篇文章主要介绍了Netty中序列化的作用及自定义协议详解,Netty自身就支持很多种协议比如Http、Websocket等等,但如果用来作为自己的RPC框架通常会自定义协议,所以这也是本文的重点,需要的朋友可以参考下
    2023-12-12
  • Springboot Redis 哨兵模式的实现示例

    Springboot Redis 哨兵模式的实现示例

    本文主要介绍了Springboot Redis 哨兵模式的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • java DecimalFormat常用方法详解

    java DecimalFormat常用方法详解

    这篇文章主要为大家详细介绍了java DecimalFormat的常用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • springboot druid mybatis多数据源配置方式

    springboot druid mybatis多数据源配置方式

    这篇文章主要介绍了springboot druid mybatis多数据源配置方式,具有很好的参考价值,希望对大家有所帮助,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java Mybatis框架由浅入深全解析中篇

    Java Mybatis框架由浅入深全解析中篇

    MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码本文将为大家深入的介绍一下MyBatis的使用
    2022-07-07
  • SpingMvc复杂参数传收总结

    SpingMvc复杂参数传收总结

    这篇文章主要为大家介绍了SpingMvc复杂参数传收总结,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Java使用Maven BOM统一管理版本号的实现

    Java使用Maven BOM统一管理版本号的实现

    这篇文章主要介绍了Java使用Maven BOM统一管理版本号的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论