Java_Spring:9. 基于 XML 的 AOP 配置

目录

1 环境搭建

1.1 第一步:准备必要的代码

1.2 第二步:拷贝必备的 jar 包到工程的 lib 目录

1.3 第三步:创建 spring 的配置文件并导入约束

1.4 第四步:配置 spring 的 ioc

1.5 第五步:抽取公共代码制作成通知

2 配置步骤

2.1 第一步:把通知类用 bean 标签配置起来

2.2 第二步:使用 aop:config 声明 aop 配置

2.3 第三步:使用 aop:aspect 配置切面

2.4 第四步:使用 aop:pointcut 配置切入点表达式

2.5 第五步:使用 aop:xxx 配置对应的通知类型

3 切入点表达式说明

4 环绕通知


  • 1 环境搭建

    • 示例:
      • 在学习 spring 的 aop 时,采用账户转账作为示例。把 spring 的 ioc 也一起应用进来。
    • 1.1 第一步:准备必要的代码

      • 此处包含了实体类,业务层和持久层代码。沿用上一章节中的代码即可。
    • 1.2 第二步:拷贝必备的 jar 包到工程的 lib 目录

      • 此处要拷贝 spring 的 ioc 和 aop 两组 jar 包
    • 1.3 第三步:创建 spring 的配置文件并导入约束

      • 此处要导入 aop 的约束
      • <?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: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/aop 
                                http://www.springframework.org/schema/aop/spring-aop.xsd">
        </beans>
    • 1.4 第四步:配置 spring 的 ioc

      • <!-- 配置 service -->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
        </bean>
        
        <!-- 配置 dao -->
        <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
            <property name="dbAssit" ref="dbAssit"></property>
        </bean>
        
        <!-- 配置数据库操作对象 -->
        <bean id="dbAssit" class="com.itheima.dbassit.DBAssit">
            <property name="dataSource" ref="dataSource"></property>
            
            <!-- 指定 connection 和线程绑定 -->
            <property name="useCurrentConnection" value="true"></property>
        </bean>
        
        <!-- 配置数据源 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///spring_day02"></property>
            <property name="user" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
    • 1.5 第五步:抽取公共代码制作成通知

      • 事务控制类
      • public class TransactionManager {
        
            //定义一个 DBAssit
            private DBAssit dbAssit ;
            
            public void setDbAssit(DBAssit dbAssit) {
                this.dbAssit = dbAssit;
            }
        
            //开启事务
            public void beginTransaction() {
        
            
                try {
                
                    dbAssit.getCurrentConnection().setAutoCommit(false);
                } catch (SQLException e) {
        
                    e.printStackTrace();
                }
            }
        
        
            //提交事务
            public void commit() {
        
                try {
                    dbAssit.getCurrentConnection().commit();
                } catch (SQLException e) {
        
                    e.printStackTrace();
                }
            }
        
            //回滚事务
            public void rollback() {
        
                try {
                    dbAssit.getCurrentConnection().rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        
            //释放资源
            public void release() {
        
                try {
                    dbAssit.releaseConnection();
                } catch (Exception e) {
        
                    e.printStackTrace();
                }
            }
        }
  • 2 配置步骤

    • 2.1 第一步:把通知类用 bean 标签配置起来

    • <!-- 配置通知 -->
      <bean id="txManager" class="com.itheima.utils.TransactionManager">
          <property name="dbAssit" ref="dbAssit"></property>
      </bean> 
    • 2.2 第二步:使用 aop:config 声明 aop 配置

      • aop:config:
        • 作用:用于声明开始 aop 的配置
      • <aop:config>
        
            <!-- 配置的代码都写在此处 -->
        </aop:config>
    • 2.3 第三步:使用 aop:aspect 配置切面

      • aop:aspect:
        • 作用:
          • 用于配置切面。
        • 属性:
          • id:给切面提供一个唯一标识。
          • ref:引用配置好的通知类 bean 的 id。
      • <aop:aspect id="txAdvice" ref="txManager">
        
            <!--配置通知的类型要写在此处-->
        </aop:aspect>
    • 2.4 第四步:使用 aop:pointcut 配置切入点表达式

      • aop:pointcut:
        • 作用:
          • 用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
        • 属性:
          • expression:用于定义切入点表达式。
          • id:用于给切入点表达式提供一个唯一标识
      • <aop:pointcut expression="execution(
            public void com.itheima.service.impl.AccountServiceImpl.transfer(
                java.lang.String, java.lang.String, java.lang.Float
            )
        )" id="pt1"/>
    • 2.5 第五步:使用 aop:xxx 配置对应的通知类型

      • aop:before
        • 作用:
          • 用于配置前置通知。指定增强的方法在切入点方法之前执行
        • 属性:
          • method:用于指定通知类中的增强方法名称
          • ponitcut-ref:用于指定切入点的表达式的引用
          • poinitcut:用于指定切入点表达式
        • 执行时间点:
          • 切入点方法执行之前执行
        • <aop:before method="beginTransaction" pointcut-ref="pt1"/>
      • aop:after-returning
        • 作用:
          • 用于配置后置通知
        • 属性:
          • method:指定通知中方法的名称。
          • pointct:定义切入点表达式
          • pointcut-ref:指定切入点表达式的引用
        • 执行时间点:
          • 切入点方法正常执行之后。它和异常通知只能有一个执行
        • <aop:after-returning method="commit" pointcut-ref="pt1"/>
      • aop:after-throwing
        • 作用:
          • 用于配置异常通知
        • 属性:
          • method:指定通知中方法的名称。
          • pointct:定义切入点表达式
          • pointcut-ref:指定切入点表达式的引用
        • 执行时间点:
          • 切入点方法执行产生异常后执行。它和后置通知只能执行一个
        • <aop:after-throwing method="rollback" pointcut-ref="pt1"/>
      • aop:after
        • 作用:
          • 用于配置最终通知
        • 属性:
          • method:指定通知中方法的名称。
          • pointct:定义切入点表达式
          • pointcut-ref:指定切入点表达式的引用
        • 执行时间点:
          • 无论切入点方法执行时是否有异常,它都会在其后面执行。
        • <aop:after method="release" pointcut-ref="pt1"/>
  • 3 切入点表达式说明

    • execution:匹配方法的执行(常用)
      • execution(表达式)
    • 表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
    • 写法说明:
      • 全匹配方式:
      • public void com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)
      • 访问修饰符可以省略
      • void com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)
      • 返回值可以使用*号,表示任意返回值
      • * com.itheima.service.impl.AccountServiceImpl.saveAccount(com.itheima.domain.Account)
      • 包名可以使用*号,表示任意包,但是有几级包,需要写几个*
      • * *.*.*.*.AccountServiceImpl.saveAccount(com.itheima.domain.Account)
      • 使用..来表示当前包,及其子包
      • * com..AccountServiceImpl.saveAccount(com.itheima.domain.Account)
      • 类名可以使用*号,表示任意类
      • * com..*.saveAccount(com.itheima.domain.Account)
      • 方法名可以使用*号,表示任意方法
      • * com..*.*( com.itheima.domain.Account)
      • 参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数
      • * com..*.*(*)
      • 参数列表可以使用..表示有无参数均可,有参数可以是任意类型
      • * com..*.*(..)
      • 全通配方式:
      • * *..*.*(..)
      • 注:
        • 通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。
        • execution(* com.itheima.service.impl.*.*(..))
  • 4 环绕通知

    • 配置方式:
    • <aop:config>
          <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"/>
          <aop:aspect id="txAdvice" ref="txManager">
              <!-- 配置环绕通知 -->
              <aop:around method="transactionAround" pointcut-ref="pt1"/>
          </aop:aspect>
      </aop:config>
    • aop:around:
      • 作用:
        • 用于配置环绕通知
      • 属性:
        • method:指定通知中方法的名称。
        • pointct:定义切入点表达式
        • pointcut-ref:指定切入点表达式的引用
      • 说明:
        • 它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
      • 注意:
        • 通常情况下,环绕通知都是独立使用的
        • /**
        • * 环绕通知
        • * @param pjp
        • * spring 框架为我们提供了一个接口:ProceedingJoinPoint,它可以作为环绕通知的方法参数。
        • * 在环绕通知执行时,spring 框架会为我们提供该接口的实现类对象,我们直接使用就行。
        • * @return
        • */
      • public Object transactionAround(ProceedingJoinPoint pjp) {
        
            //定义返回值
            Object rtValue = null;
        
            try {
        
                //获取方法执行所需的参数
                Object[] args = pjp.getArgs();
        
                //前置通知:开启事务
                beginTransaction();
        
                //执行方法
                rtValue = pjp.proceed(args);
        
                //后置通知:提交事务
                commit();
            }catch(Throwable e) {
        
                //异常通知:回滚事务
                rollback();
                e.printStackTrace();
            }finally {
        
                //最终通知:释放资源
                release();
            }
        
            return rtValue;
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/4972.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法笔记--数据结构与算法基本知识

目录 1--数据结构 2--算法 3--算法分析 4--实例1&#xff1a;普通算法与秦九韶算法的运算效率比较 5--实例2&#xff1a;最大子列和问题 5-1--暴力求解法 5-2--分而治之 5-3--动态规划 5-4--完整代码 1--数据结构 定义&#xff1a;所有数据元素以及数据元素之间的关系…

JS手写Promise(详细过程)

PS&#xff1a;JS手写Promise方法的整理在下一篇文章 手写Promise的API(resolve,reject,then,catch,finally,all)_Eric加油学&#xff01;的博客-CSDN博客 1、基础版Promise 首先&#xff0c;通过一个简单的Promise例子回顾其使用 const promise new Promise((resolve, rej…

为什么诚信是项目管理的关键部分?

由于有许多需要指导的活动部件和风险&#xff0c;管理一个新项目可能是一项具有挑战性的工作。在一些对质量有着严格要求的行业&#xff0c;项目结构、设定目标、跟踪状态、风险管理和资源管理等项目管理原则尤为重要&#xff0c;而领导这项工作的是诚信。那么&#xff0c;究竟…

IP 归属用 Ip2region 就够了

文章目录Ip2region 简介是什么特性支持的编程语言案例实操依赖获取IP输入流转化解析IP测试抖音、微博、小红书等各平台相继上线" 网络用户IP地址显示功能"&#xff0c; 境外显示 国家&#xff0c; 境内显示到 省市&#xff0c;且该功能无法关闭&#xff0c;IP地址为强…

【新2023Q2模拟题JAVA】华为OD机试 - 分苹果

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:分苹果 题目 AB两个人把苹果…

第16章_变量、流程控制与游标

第16章_变量、流程控制与游标 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xf…

ClickHouse学习笔记(三):MergeTree 原理解析

文章目录1、简介2、MergeTree 创建方式与存储结构2.1、MergeTree 的创建方式2.2、MergeTree 的存储结构3、MergeTree 数据分区3.1、分区目录的命名规则3.2、分区目录合并过程4、一级索引4.1、索引粒度4.2、索引生成4.3、索引查询5、二级索引6、数据存储7、数据标记8、协同总结8…

BootStrap4:栅格系统

1、container容器 container&#xff1a;固定宽度的容器container-fluid&#xff1a;响应式容器 2、栅格选项 Bootstrap4 总共有五个栅格等级&#xff0c;每个响应式分界点隔出一个等级 Ps&#xff1a;.row上带有margin-left: -15px;margin-right: -15px;属性&#xff0c;你…

【22年蓝桥杯】十三届蓝桥杯真题JavaB组解析+代码(带你复习知识点)(一)

试题 A: 星期计算 【填空题】 答案&#xff1a;7 解析&#xff1a;直接对所给数进行取余&#xff0c;然后直接再加6&#xff08;注意&#xff1a;不能直接让20^226再对7进行取余操作&#xff0c;这是不对的&#xff0c;这个6可以看成已经取余过了。&#xff09; 直接取余的话可…

Linux系统安装部署及配置Grafana

TOC 用于 UI 展示 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpm1 安装 grafana 1.1 下载安装 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpmsudo yum install grafana-8.0.3-1.x86_64.rpm1.2 启动&状态查看 sudo syst…

PHP初级教程------------------(3)

目录 文件包含 文件包含的作用 文件包含四种形式 文件加载原理 Include和require区别 文件加载路径 文件嵌套包含 函数 函数的基本概念 函数定义语法 函数命名规范 参数详解 形参 实参 默认值 引用传递 函数体 函数返回值 ​作用域 静态变量 可变函数 匿名函数 闭包 伪类型 文件…

作为一个数学专业的学生,我是怎么看待编程的?

1.概况 博主的专业是数学与应用数学&#xff0c;简称应数。虽然后面跟了个应用数学&#xff0c;但是这个专业应该是本科阶段最接近数学的专业了。我认为这个专业使我具有如下的几个优势&#xff1a; 数学的学习使我具有较强的思维能力。编程本质上就是通过写代码的方式来解决…

大数据Flink进阶(八):Apache Flink架构介绍

Apache Flink架构介绍 一、Flink组件栈 在Flink的整个软件架构体系中,同样遵循这分层的架构设计理念,在降低系统耦合度的同时,也为上层用户构建Flink应用提供了丰富且友好的接口。

山东大学机器学习大作业

数据处理与可视化这里是DLRM模型数据集预处理模块&#xff1a;args.ln_emb ln_emb.tolist() m_spa args.arch_sparse_feature_sizeln_emb np.asarray(ln_emb)num_fea ln_emb.size 1 # num sparse num dense featuresm_den_out ln_bot[ln_bot.size - 1]Sparse fea 26, D…

Java设计模式-3、单例模式

单例模式 单例模式属于创建型模式&#xff0c;⼀个单例类在任何情况下都只存在⼀个实例&#xff0c; 构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例&#xff0c;对外提供⼀ 个静态公有⽅法获取实例。 优点是内存中只有⼀个实例&#xff0c;减少了开销&#xff0c;尤…

代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串

今天的练习基本就是回溯法组合问题&#xff0c;这一节只要看labuladong即可。 组合问题&#xff1a; 39. 组合总和---------------------形式三&#xff0c;元素无重可复选 链接&#xff1a;代码随想录 一次对&#xff0c;同样在进入下次循环时&#xff0c;注意startindex是从j…

欧莱雅校招负责人张泽宇:拥抱Z世代,探索新玩法

作为校招HR&#xff0c;你在雇主品牌创新实践的路上做过什么尝试&#xff1f; 2020年&#xff0c;欧莱雅正式推出了全新的雇主品牌价值主张 —— 敢为敢超越&#xff0c;就是欧莱雅&#xff08;Freedom to go beyond, thats the beauty of L’ORAL&#xff09;&#xff0c;鼓励…

使用ChatGPT进行AI对话

1.ChatGPT简介 ChatGPT是美国人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具&#xff0c;使用了Transformer神经网络架构&#xff0c;也是GPT-3.5架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;拥有语言理解和文本生成能力&#xff0c…

C/C++ 日期 时间 函数总结

使用C标准库 有四个与时间相关的类型&#xff1a;clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数 头文件 #include <time.h> #include <stdio.h> tm 结构: struct tm {int tm_sec; // 秒&#xff0c;…

隐私计算-TEE执行环境

一、TEE 的定义 论述完 TEE 的概念后&#xff0c;接下来进一步解析 TEE 的深层定义。目前对于 TEE 的定义有很多种形式&#xff0c;针对于不同的安全性需求和平台&#xff0c;TEE 的定义也不尽相同&#xff0c;但在所有 TEE 的定义中都会包含两个最关键的点&#xff1a;独立执…