0

0

Spring中的AOP以及切入点表达式和各种通知

爱谁谁

爱谁谁

发布时间:2025-07-23 11:54:01

|

181人浏览过

|

来源于php中文网

原创

大家好,我们又见面了,我是你们的朋友全栈君。

视频功能已经通过审核,大家可以观看视频了!记得关注哦~

注意:由于网络原因,视频的前一两分钟可能会有些模糊,稍等一会儿就会清晰。

Spring AOP系列将帮助你深入了解Spring AOP的背景和原理。

在上一篇中,我们讨论了动态代理:Java中动态代理的两种方式——JDK动态代理和cglib动态代理,以及它们的区别。

我们使用上一篇的方法来增强目标方法,实现代码的解耦是可行的,但仍然需要自己生成代理对象,手动编写拦截器,在拦截器中手动将增强内容与目标方法结合起来,这样的操作还是有些繁琐。那么,有没有更好的解决方案呢?

答案是:有的!这就是Spring的AOP,这是我们最终想要引出的重点!

有了Spring的AOP后,就不需要自己编写代码了,只需在配置文件中进行配置,告诉Spring哪些类需要生成代理类,哪个类是增强类,以及是在目标方法执行前还是执行后进行增强。配置好这些后,Spring会根据你的配置生成代理对象,并将增强内容与目标方法结合起来。这相当于自己编写代码也能实现与AOP类似的功能,但有了Spring AOP后,Spring帮你做了这些事情,而且Spring将其做成了可配置化,使用起来非常简单且灵活。

我们之前使用的JDK动态代理和cglib动态代理,这两种在Spring的AOP中都有应用。Spring会根据不同的情况决定是使用JDK的动态代理生成代理对象,还是使用cglib生成代理对象,本篇会详细讲解这些内容。

在讨论Spring AOP之前,需要了解一些涉及到的术语。

1、Spring AOP中的术语概念 翻阅Spring AOP相关的文档,会发现里面有很多概念性的东西,很多术语和概念都写得很玄乎,读好几遍都读不懂。我个人认为以下几个术语是关键,必须掌握:

切面类:就是要执行的增强方法所在的类,比如我们例子中的MyTransaction类。

通知:切面类中的增强方法,比如我们例子中的beginTransaction()方法和commit()方法。

目标方法:要执行的目标方法,比如我们例子中的savePerson()方法。

织入:将通知和目标方法结合,形成代理对象的过程称为织入。

代理对象的方法 = 通知(增强方法) + 目标方法

上述解释是我个人的理解。

了解这些术语后,下面我们通过代码来实现一下,感受一下Spring AOP的魅力。

jquery带商品分类侧边栏列表的商城导航菜单
jquery带商品分类侧边栏列表的商城导航菜单

这是一款使用jquery制作的带商品分类侧边栏列表的商城导航菜单。该商城菜单兼容ie8浏览器。用户可以通过点击左侧的下拉菜单来查看各种商品的列表,非常实用和方便。 使用方法 在页面中引入样式文件style.css和jquery.min.js文件。

下载

2、使用Spring AOP的代码实现

package com.cj.study.spring.aop;
public interface PersonService {
    public String savePerson();
    public void updatePerson();
    public void deletePerson();
}
package com.cj.study.spring.aop;
public class PersonServiceImpl implements PersonService {
    @Override
    public String savePerson() {
        System.out.println("添加");
        return "保存成功!";
    }
    @Override
    public void updatePerson() {
        System.out.println("修改");
    }
    @Override
    public void deletePerson() {
        System.out.println("删除");
    }
}
package com.cj.study.spring.aop;
//切面类
public class MyTransaction {
    //切面里的通知方法
    public void beginTransaction(){
        System.out.println("开启事务 ");
    }
    //切面里的通知方法
    public void commit(){
        System.out.println("提交事务");
    }
}
package com.cj.study.spring.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("com/cj/study/spring/aop/applicationContext.xml");
        PersonService proxyPersonService = (PersonService) context.getBean("personService");
        String returnValue = proxyPersonService.savePerson();
        System.out.println(returnValue);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    <bean class="com.cj.study.spring.aop.PersonServiceImpl" id="personService"></bean>
    <bean class="com.cj.study.spring.aop.MyTransaction" id="myTransaction"></bean>
    <aop:config>
        <aop:pointcut expression="execution(* com.cj.study.spring.aop.*.*(..))" id="perform"/>
        <aop:aspect ref="myTransaction">
            <aop:before method="beginTransaction" pointcut-ref="perform"/>
        </aop:aspect>
        <aop:aspect ref="myTransaction">
            <aop:after method="commit" pointcut-ref="perform"/>
        </aop:aspect>
    </aop:config>
</beans>

可以设置断点查看:

Spring中的AOP以及切入点表达式和各种通知 发现返回的对象是$Proxy4,说明返回的是代理类的对象。

最终的运行结果:

Spring中的AOP以及切入点表达式和各种通知 效果和我们自己编写的一样,但Spring AOP将其做成了配置化的,使用起来非常方便。

讲完例子后,下面讲解具体的细节。

3、AOP配置文件内容讲解

Spring中的AOP以及切入点表达式和各种通知 这是我们上述例子中的配置文件。

(1)、导入目标类和切面类,就是将目标类和切面类放入Spring容器中,让Spring帮你生成。

(2)、aop:pointcut 是指切入点。

(3)、expression 是指切入点表达式。

(4)、aop:aspect 是指上边讲的切面类。

(5)、aop:before、aop:after 是指上边讲的通知,通知有很多种,前置通知、后置通知、环绕通知、最终通知、异常通知,下面会详细讲解。

3.1、切入点表达式execution 切入点和切入点表达式是用来告诉Spring哪些类需要Spring为你生成代理对象,这个非常重要。

要彻底了解这个表达式的意思,首先需要知道Java中一个方法最完整的描述是什么样的。

Spring中的AOP以及切入点表达式和各种通知 截图上的execution是AOP文档中给出的表达式示例,下面这一行是Java中一个方法最完整的描述(以Object中的wait方法为例)。

对应的含义我进行了标注,并且与图上的execution表达式做了一一对应。

下面举几个表达式的例子,进一步帮助大家理解(*代表通配符):

execution(public * *(..))  所有的公共方法
execution(* set*(..))  以set开头的任意方法
execution(* com.ci.service.AccountService.*(..)) com.cj.service.AccountService类中的所有的方法
execution(* com.cj.service.*.*(..))  com.cj.service包中的所有的类的所有的方法
execution(* com.cj.service..*.*(..)) com.cj.service包及子包中所有的类的所有的方法
execution(* com.cj.spring.aop..*.*(String,?,Integer))  com.cj.spring.aop包及子包中所有的类的有三个参数
                                                            且第一个参数为String,第二个参数为任意类型,
                                                            第三个参数为Integer类型的方法

理解了这些后,我们就可以根据自己想配置的路径进行配置了。

3.2、AOP中的各种通知

通知:
   1、前置通知
      1、在目标方法执行之前执行
      2、无论目标方法是否抛出异常,都执行,因为在执行前置通知的时候,目标方法还没有执行,还没有遇到异常
   2、后置通知
      1、在目标方法执行之后执行
      2、当目标方法遇到异常,后置通知将不再执行
      3、后置通知可以接受目标方法的返回值,但是必须注意:
               后置通知的参数的名称和配置文件中returning="var"的值是一致的
   3、最终通知:
      1、在目标方法执行之后执行
      2、无论目标方法是否抛出异常,都执行,因为相当于finally
   4、异常通知
      1、接受目标方法抛出的异常信息
      2、步骤
           在异常通知方法中有一个参数Throwable  ex
           在配置文件中
              <after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"></after-throwing>
   5、环绕通知
       1、如果不在环绕通知中调用ProceedingJoinPoint的proceed,目标方法不会执行
       2、环绕通知可以控制目标方法的执行

3.3、Spring AOP的具体加载步骤,理解这个非常重要!!!

springAOP的具体加载步骤:
   1、当spring容器启动的时候,加载了spring的配置文件
   2、为配置文件中所有的bean创建对象
   3、spring容器在创建对象的时候它会解析aop:config的配置
            解析切入点表达式,用切入点表达式和纳入spring容器中的bean做匹配
            如果匹配成功,则会为该bean创建代理对象,代理对象的方法=目标方法+通知
            如果匹配不成功,则为该bean创建正常的对象
            其实就是你通过表达式告诉Spring哪些bean需要它帮你生成代理对象而不是生成原有的正常对象
      理解这一点相当重要!
   4、在客户端利用context.getBean获取对象时,如果该对象有代理对象则返回代理对象,如果没有代理对象,则返回目标对象
注意:如果目标类实现了接口,spring容器会采用jdk的动态代理产生代理对象,产生的代理类和目标类实现了相同的接口;如果目标类没实现接口,spring容器会采用cglib的方式产生代理对象,产生的代理类是目标类的子类

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

154

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

88

2026.01.26

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

435

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

601

2023.08.10

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

28

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

68

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

164

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

84

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

114

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Spring中文手册
Spring中文手册

共0课时 | 0.6万人学习

马士兵spring视频教程
马士兵spring视频教程

共25课时 | 9.2万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号