Java_Spring之XML 的 AOP 配置

 更新时间:2023年04月06日 10:40:16   作者:JiangTao_xlili  
这篇文章主要介绍了Java_Spring中基于XML的AOP配置,上篇讲到的是基于注解的AOP配置,对XML感兴趣的同学可以参考阅读本文

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&gt;

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;
}

到此这篇关于Java_Spring之XML 的 AOP 配置的文章就介绍到这了,更多相关Spring 基于XML的AOP配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis中bind标签和concat的使用说明

    mybatis中bind标签和concat的使用说明

    这篇文章主要介绍了mybatis中bind标签和concat的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Sentinel初始化启动流程详细介绍

    Sentinel初始化启动流程详细介绍

    Sentinel是一个分布式系统的流量控制组件,它可以实现限流与流控及降级等功能,提高系统的稳定性和可靠性,这篇文章主要介绍了Sentinel的初始化流程,感兴趣想要详细了解可以参考下文
    2023-05-05
  • Java Hibernate中的查询策略和抓取策略

    Java Hibernate中的查询策略和抓取策略

    Hibernate是一种Java对象关系映射框架,提供了多种查询和抓取策略,用于优化数据库访问性能。查询策略包括延迟加载、立即加载、查询缓存等,抓取策略包括join抓取、子查询抓取、批量抓取等。这些策略可以根据实际应用场景进行选择和配置,提高数据访问的效率和稳定性
    2023-04-04
  • spring boot 动态生成接口实现类的场景分析

    spring boot 动态生成接口实现类的场景分析

    本文不具体介绍动态代理,主要看一下它在springboot项目中的实际应用,下面我们模仿feign来实现一个调用三方接口的 httpclient,感谢的朋友跟随小编一起看看吧
    2021-11-11
  • Java算法真题详解运用单调栈

    Java算法真题详解运用单调栈

    一般使用单调栈无非两个方向,单调递减,单调递增。单调递增栈:存进去的数据都是增加的,碰到减少的时候,这时就要进行操作了。单调递减栈:存进去的数据都是减少的,碰到增加的时候,这时就要进行操作了,下面我们在真题中运用它
    2022-07-07
  • Java引用类型interface的用法总结

    Java引用类型interface的用法总结

    这篇文章主要为大家详细介绍了Java中引用类型interface的用法的相关资料,文中的示例代码讲解详细,对我们学习Java有一定帮助,感兴趣的可以了解一下
    2022-10-10
  • Mybatis-Plus自动生成代码的实现示例

    Mybatis-Plus自动生成代码的实现示例

    在工作中,程序员很多时候都是在写类似的代码,可以使用自动生成代码,本文主要介绍了Mybatis-Plus自动生成代码的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Java压缩/解压文件的实现代码

    Java压缩/解压文件的实现代码

    本文通过实例代码给大家分享了Java压缩/解压文件的方法,需要的朋友参考下吧
    2017-09-09
  • RabbitMQ 如何解决消息幂等性的问题

    RabbitMQ 如何解决消息幂等性的问题

    这篇文章主要介绍了RabbitMQ 如何解决消息幂等性的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java对ArrayList排序代码示例

    java对ArrayList排序代码示例

    本文通过代码示例给大家介绍java对arraylist排序,代码简洁易懂,感兴趣的朋友一起学习吧
    2015-11-11

最新评论