热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Spring中基于XML的AOP配置详解

这篇文章主要介绍了Spring中基于XML的AOP配置,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

1. 准备工作

1.1 创建工程 day03_eesy_03SpringAOP

1.2 在配置文件pom.xml中添加依赖

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

 4.0.0

 com.itheima
 day03_eesy_03springAOP
 1.0-SNAPSHOT

 jar

 
 
  org.springframework
  spring-context
  5.2.4.RELEASE
 

 
  org.aspectj
  aspectjweaver
  1.9.5
 
 

说明: aspect依赖是用来声明切入点坐标的

1.3 编写业务层代码

1.创建包 service

2.创建业务层接口IAccountService.java

/**
 * 账户的业务层接口
 */
public interface IAccountService {

 /**
 * 模拟保存账户
 */
 void saveAccount();

 /**
 * 模拟更新账户
 */
 void updateAccount(Integer i);
 /**
 * 模拟删除账户
 */
 int deleteAccount();
}

3.创建业务层实现类AccountServiceImpl.java

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements IAccountService {
 public void saveAccount() {
 System.out.println("执行了保存");
 }

 public void updateAccount(Integer i) {
 System.out.println("执行力更新");
 }

 public int deleteAccount() {
 System.out.println("执行了删除");
 return 0;
 }
}

4.创建日志类

&#8203; 该类为用于记录日志的工具类,它里面提供了公共的代码(通知)

Logger.java

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {

 /**
 * 用于打印日志,计划让其在切入点方法执行之前执行(切入点方法就是业务层方法)
 */
 public void printLog(){
 System.out.println("Logger类中的printLog方法开始记录日志了");
 }
}

2. 进行配置

创建配置文件 bean.xml

先添加包含AOP的约束,后添加配置

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 

 

 
 

 
 
 
 
  
  
 
 

说明: 切入点表达式最好按软件的提示写,自己直接手写在测试时容易报错

3. 创建测试类AOPTest.java

/**
 * 测试AOP的配置
 */
public class AOPTest {
 public static void main(String[] args) {
 //1.获取容器
 ApplicationContext applicatiOnContext= new ClassPathXmlApplicationContext("bean.xml");
 //2.获取对象
 IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
 accountService.saveAccount();
 }
}

4. 运行结果

5. 目录结构

6. 切入点表达式写法补充

6.1 介绍


6.2 在bean.xml中表示

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 

 

 
 

 
 
 
 
  
  
 
 

6.3 在测试类AOPTest.java中测试

/**
 * 测试AOP的配置
 */
public class AOPTest {
 public static void main(String[] args) {
 //1.获取容器
 ApplicationContext applicatiOnContext= new ClassPathXmlApplicationContext("bean.xml");
 //2.获取对象
 IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
 accountService.saveAccount();
 accountService.updateAccount(1);
 accountService.deleteAccount();
 }
}

6.4 运行结果

7. 四种通知类型补充

 7.1 在Logger.java类中添加方法

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {

 /**
 * 前置通知
 */
 public void beforePrintLog(){
 System.out.println("前置通知:Logger类中的printLog方法开始记录日志了");
 }

 /**
 * 后置通知
 */
 public void afterReturningPrintLog(){
 System.out.println("后置通知:Logger类中的printLog方法开始记录日志了");
 }
 /**
 * 异常通知
 */
 public void afterThrowingPrintLog(){
 System.out.println("异常通知:Logger类中的printLog方法开始记录日志了");
 }
 /**
 * 最终通知
 */
 public void afterPrintLog(){
 System.out.println("最终通知:Logger类中的printLog方法开始记录日志了");
 }
}

7.2 在bean.xml中进行配置

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 


 
 

 
 
 
 
  
  

  
  

  
  

  
  
 
 

7.3 在测试类AOPTest.java中运行

/**
 * 测试AOP的配置
 */
public class AOPTest {
 public static void main(String[] args) {
 //1.获取容器
 ApplicationContext applicatiOnContext= new ClassPathXmlApplicationContext("bean.xml");
 //2.获取对象
 IAccountService accountService = (IAccountService) applicationContext.getBean("accountService");
 accountService.saveAccount();

 }
}

7.4 运行结果

8. 通用化切入点表达式

用于解决在bean.xml文件中配置通知时多次写切入点表达式的问题

使用 aop:pointcut标签,在bean.xml中进行配置

8.1 在aop:aspect标签内部使用aop:pointcut

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 


 
 

 
 
 
 
  
  

  
  

  
  

  
  


  
  
 
 

运行结果:

此时,aop:pointcut定义的切入点表达式只能在当前切面中使用

8.2 在aop:aspect标签外部使用aop:pointcut

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 


 
 

 
 

 
 
 
 
 
  
  

  
  

  
  

  
  
 
 

运行结果:

此时所有的切面都能使用该aop:pointcut定义的切入点表达式

主要: 当在aop:aspect标签外部使用aop:pointcut标签定义切入点表达式的时候,由于使用的约束的规定, aop:pointcut标签只能在 aop:aspect标签上方

9. Spring的环绕通知

9.1 在Logger.java中添加实现环绕通知的方法 aroundPringLog

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {
 /**
 * 环绕通知
 *
 */
 public void aroundPringLog(){
  System.out.println("Logger类中的aroundPringLog方法开始记录日志了");
 }

}

9.2 在bean.xml中完成配置

<&#63;xml version="1.0" encoding="UTF-8"&#63;>


 
 


 
 

 
 
 
 

 
 
  
  
 
 

9.3 此时运行结果

9.4 问题分析

此时只执行了通知方法,而切入点方法没有执行

原因:

&#8203; 通过对比动态的代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而本案例中的代码没有

9.5 完善aroundPringLog方法

Logger.java

/**
 * 用于记录日志的工具类,它里面提供了公共的代码
 */
public class Logger {
 /**
 * 环绕通知
 * 问题:
 * 当我们配置了环绕通知之后,切入点方法没有执行,而通知方法执行了
 * 分析:
 * 通过对比动态的代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的代码中没有
 * 解决:
 * Spring框架为我们提供了一个接口,ProceedingJoinPoint,该接口有一个方法proceed(),此方法就相当于明确调用切入点方法
 * 该接口可以作为环绕通知的方法参数, 在程序执行的时候,Spring框架会为我们提供该接口供我们使用
 *
 * Spring的环绕通知:
 * 他是Spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式
 */
 public Object aroundPringLog(ProceedingJoinPoint proceedingJoinPoint){

 Object returnValue = null;
 try {

  Object[] args = proceedingJoinPoint.getArgs(); //得到方法执行所需要的参数

  System.out.println("Logger类中的aroundPringLog方法开始记录日志了-----前置");

  returnValue = proceedingJoinPoint.proceed(args); //明确调用业务层方法,切入点方法

  System.out.println("Logger类中的aroundPringLog方法开始记录日志了-----后置");

  return returnValue;
 }catch (Throwable throwable){
  System.out.println("Logger类中的aroundPringLog方法开始记录日志了-----异常");
  throw new RuntimeException(throwable);
 }finally {
  System.out.println("Logger类中的aroundPringLog方法开始记录日志了-----最终");
 }
 }

}

9.6 运行结果

9.7 目录结构

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


推荐阅读
  • 使用Jenkins构建Java项目实践指南
    本指南详细介绍了如何使用Jenkins构建Java项目,包括环境搭建、工具配置以及项目构建的具体步骤。 ... [详细]
  • ServletContext接口在Java Web开发中扮演着重要角色,它提供了一种方式来获取关于整个Web应用程序的信息。通过ServletContext,开发者可以访问初始化参数、共享数据以及应用资源。 ... [详细]
  • 本文探讨如何利用Java反射技术来模拟Webwork框架中的URL解析过程。通过这一实践,读者可以更好地理解Webwork及其后续版本Struts2的工作原理,尤其是它们在MVC架构下的角色。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 在Linux系统上构建Web服务器的详细步骤
    本文详细介绍了如何在Linux系统上搭建Web服务器的过程,包括安装Apache、PHP和MySQL等关键组件,以及遇到的一些常见问题及其解决方案。 ... [详细]
  • 在使用Maven进行项目构建时,由于依赖库的下载速度慢常常让人感到沮丧,这直接影响了开发效率和学习热情。幸运的是,阿里云提供了一个快速的国内镜像服务,能够显著提升Maven项目的构建速度。 ... [详细]
  • 本文探讨了使用Filter作为控制器的优势,以及Servlet与Filter之间的主要差异。同时,详细解析了Servlet的工作流程及其生命周期,以及ServletConfig与ServletContext的区别与应用场景。 ... [详细]
  • Java EE CDI:解决依赖关系冲突的实例
    在本教程中,我们将探讨如何在Java EE的CDI(上下文和依赖注入)框架中有效解决依赖关系的冲突问题。通过学习如何使用限定符,您将能够为应用程序的不同客户端提供多种接口实现,并确保每个客户端都能正确调用其所需的实现。 ... [详细]
  • Flowable 6.6.0 表单引擎在Web应用中的集成与使用
    本文档提供了Flowable 6.6.0版本中表单引擎在Web应用程序中的配置和使用指南,包括表单引擎的初始化、配置以及在Web环境下的具体实现方法。 ... [详细]
  • 本文详细介绍了 Java 中 freemarker.ext.dom.NodeModel 类的 removeComments 方法,并提供了多个实际使用的代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了 Kubernetes 集群管理工具 kubectl 的基本使用方法,涵盖了一系列常用的命令及其应用场景,旨在帮助初学者快速掌握 kubectl 的基本操作。 ... [详细]
  • 本文将指导您如何在Docker环境中高效地搜索、下载Redis镜像,并通过指定或不指定配置文件的方式启动Redis容器。同时,还将介绍如何使用redis-cli工具连接到您的Redis实例。 ... [详细]
  • Lua编程进阶:数组与迭代器详解
    本文深入探讨了Lua语言中的数组和迭代器,通过实例讲解了一维数组、多维数组的使用方法及迭代器的工作原理。 ... [详细]
  • 本文提供了2023年最新的解决方案,帮助用户了解如何在移动设备上顺利访问和浏览PHP网页,涵盖从基础设置到高级技巧的全方位指导。 ... [详细]
  • 本文详细介绍了 Java 中 com.amazonaws.auth.SystemPropertiesCredentialsProvider 初始化方法的使用方式,并提供了多个实际的代码示例,帮助开发者更好地理解和应用这一方法。 ... [详细]
author-avatar
祢好世界末日
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有