Spring-AOP

目录

一、引入AOP

二、核心AOP概念和术语

三、切点表达式

四、Spring实现AOP

(一)@AspectJ的支持

1 、基于注解开发

1.1 引入依赖

1.2  实现目标类

1.3 定义切面类(日志管理)

1.4 将目标类和切面类纳入Spring容器

1.5 开启组件扫描、自动代理

1.6 测试

2、基于XML方式开发

(二) 基于Schema的AOP支持

1.1 声明Aspect

1.2 编写Spring配置文件(目标类使用组件扫描)

1.3 测试

五、总结


AOP (Aspect Oriented Programming)意为面向切面编程,通过预编译和运行期间动态代理实现程序功能的一种技术。Spring中通过JDK动态代理和Cglib动态代理技术实现AOP。Spring可以灵活切换这两种动态代理方式,如果代理接口会默认使用JDK动态代理,如果代理某个类,这个类没有实现接口,就会切换Cglib。此外,我们也可以配置Spring选择。


一、引入AOP

    系统开发中不仅要做核心业务, 还需要做一些系统业务,例如:事务管理、运行记录、安全日志等,这些系统业务被称为交叉业务。

    如果在每一个业务处理过程当中,都掺杂这些交叉业务进去的话,存在两方面问题:

  • 交叉业务代码在多个业务流程中反复出现,显然这些交叉代码没有得到复用。并且修改这些交叉代码,修改起来很麻烦。
  • 程序员无法专注核心业务代码的编写,在编写核心代码的同时还需要处理这些交叉业务。

     见上图,方便理解AOP思想。将非核心业务与核心业务进行分离,同时把这些非核心业务切入到业务流程当中的过程称为AOP。 

二、核心AOP概念和术语

  • JoinPoint(连接点)程序执行过程中的一个点,例如一个方法的执行或一个异常的处理。在Spring AOP中,一个连接点总是代表一个方法的执行。
  • 切点(Pointcut)真正切入切面的方法,指定哪些方法需要切入 
  • 通知(Advice)一个切面在特定连接点采取的行动,根据通知类型确定执行流程。通知包括前置通知、后置通知、环绕通知等。
  • Aspect(切面)通知 + 切面 
  • Target object(目标对象) 被一个或多个切面所 advice 的对象。也被称为 "advised object"。由于Spring AOP是通过使用运行时代理来实现的,这个对象总是一个被代理的对象。

  • AOP proxy(代理对象) 一个由AOP框架创建的对象,以实现切面契约(advice 方法执行等)。在Spring框架中,AOP代理是一个JDK动态代理或CGLIB代理。

  • Weaving(织入)将通知应用到目标对象的过程。

三、切点表达式

    切点表达式用来定义通知往哪些方法切入。

切点表达式语法格式

execution( [访问权限修饰符] 返回值类型 [全限定类名] 方法名(形式参数列表)[异常] )

     构成 @Pointcut 注解的值的 pointcut 表达式是一个常规的AspectJ pointcut表达式。关于AspectJ的 pointcut 语言的全面讨论,请参见 《AspectJ编程指南》(以及 AspectJ 5开发者笔记 的扩展)或关于AspectJ的书籍之一(如Colyer等人的《Eclipse AspectJ》,或Ramnivas Laddad的《AspectJ in Action》)。 

四、Spring实现AOP

(一)@AspectJ的支持

1 、基于注解开发

1.1 引入依赖
<!--spring context依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version>
</dependency>
<!--spring aop依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.9.RELEASE</version>
</dependency>
<!--spring aspects依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.1.9.RELEASE</version>
</dependency>
1.2  实现目标类
@Service("userService")
public class UserServiceImpl implements UserService {@Autowiredprivate UserMongoDao userMongoDao;@Overridepublic User login(String name, String password) {Document doc = new Document();doc.put("name", name);doc.put("password", password);ArrayList<Document> list = userMongoDao.queryAll(doc);User user = null;if (! list.isEmpty()) {Document document = list.get(0);user = new User();user.setId((ObjectId) document.get("_id"));user.setName((String) document.get("name"));}return user;}
}
1.3 定义切面类(日志管理)
package com.zookin.service.aspect;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;@Component
@Aspect
public class LoggerAspect {private static final Logger LOGGER = LoggerFactory.getLogger(LoggerAspect.class);@Pointcut("execution(public * com.zookin.service.*.*(..))")public void logPointcut() {}@Before("logPointcut()")public void beforeAdvice(JoinPoint joinPoint) {LOGGER.info("before advice:" + joinPoint.getSignature().getName());}@Around("logPointcut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();LOGGER.info("Method:" + joinPoint.getSignature().getName() + " execution time:" + (endTime - startTime) + "ms");return result;}@AfterReturning(pointcut = "logPointcut()", returning = "result")public void afterReturningAdvice(JoinPoint joinPoint, Object result) {LOGGER.info("After returning from method: " + joinPoint.getSignature().getName() + ", result: " + result);}@AfterThrowing(pointcut = "logPointcut()", throwing = "exception")public void afterThrowingAdvice(JoinPoint joinPoint, Exception exception) {LOGGER.error("Exception thrown from method: " + joinPoint.getSignature().getName() + ", exception: " + exception.getMessage());}}
1.4 将目标类和切面类纳入Spring容器

  目标类添加@Service注解,切面类添加@Component、@Aspect注解。 

1.5 开启组件扫描、自动代理
<?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.xsdhttp://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.zookin.service"/><aop:aspectj-autoproxy proxy-target-class="true"/></beans>
1.6 测试
@Testpublic void loginTest() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = applicationContext.getBean("userService", UserService.class);User login = userService.login("zookin", "zookin");System.out.println(login);
}

2、基于XML方式开发

略.... 

(二) 基于Schema的AOP支持

  如果喜欢基于XML的格式,Spring也提供了对使用 aop 命名空间标签定义切面的支持。它支持与使用 @AspectJ 风格时完全相同的 pointcut 表达式和advice种类。要使用本节描述的 aop 命名空间标签,你需要导入 spring-aop schema,如 基于XML schema的配置 中所述。

 在你的Spring配置中,所有的aspect和 advisor元素都必须放在一个 <aop:config> 元素(你可以在一个应用上下文配置中拥有多个 <aop:config> 元素)。一个 <aop:config> 元素可以包含 pointcut、 advisor 和 aspect 元素(注意这些必须按顺序声明)。

1.1 声明Aspect

      通过使用 <aop:aspect> 元素来声明一个切面,并通过使用 ref 属性来引用支持 Bean,如下例所示。

<aop:config><aop:aspect id="myAspect" ref="aBean">...</aop:aspect>
</aop:config><bean id="aBean" class="...">...
</bean>

支持切面的Bean(本例中的 aBean)当然可以像其他Spring Bean一样被配置和依赖注入。 

1.2 编写Spring配置文件(目标类使用组件扫描)

<?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.xsdhttp://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.zhj.service"/><aop:aspectj-autoproxy proxy-target-class="true"/><bean id="timerAspect" class="com.zhj.service.aspect.TimerAspect"></bean><aop:config><aop:pointcut id="aa" expression="execution(* com.zhj.service.CommodityService.*(..))"/><aop:aspect ref="timerAspect"><aop:around method="time" pointcut-ref="aa"/></aop:aspect></aop:config></beans>

1.3 测试

    @Testpublic void commodityTest() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");CommodityService commodityService = applicationContext.getBean("commodityService", CommodityService.class);ArrayList<Commodity> commodities = commodityService.queryCommodity("自行车", 0, null);}

 


五、总结

   AOP是Spring框架的核心组件,AOP蕴含的底层原理十分值得了解和挖掘。Spring 框架自5.0版本以来,集成了Log4j、SLF4j框架,本文我简单地整合日志框架来说明AOP的实现,此外我们可以使用AOP实现事务管理,见上一篇博客。上述内容如果有错误的地方,希望大佬们可以指正。我一直在学习的路上,您的帮助使我收获更大!觉得对您有帮助的话,还请点赞支持!我也会不断更新文章!Spring-事务支持icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/134687195

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JFrog Artifactory—高性能软件制品管理仓库

产品概述 JFrog Artifactory是一个可扩展的通用二进制存储库管理器&#xff0c;可在整个应用程序开发和交付过程中自动管理工件和依赖项。JFrog Artifactory支持大多数开发语言&#xff0c;是整个DevOps流水线中大多数软件包、容器映像和Helm图表的单一数据源。Artifactory对元…

四.多表查询

多表查询 1.一个案例引发的多表连接1.1案例说明1.2 笛卡尔积&#xff08;或交叉连接&#xff09;的理解1.3案例分析与问题解决 2.多表查询分类讲解分类1&#xff1a;等值连接vs非等值连接分类2&#xff1a;自连接vs非自连接分类3&#xff1a;内连接vs外连接 3.SQL99语法实现多表…

TsuKing: Coordinating DNS Resolvers and Queries into Potent DoS Amplifiers

目录 笔记后续的研究方向摘要引言之前的工作。我们的研究贡献 TsuKing: Coordinating DNS Resolvers and Queries into Potent DoS Amplifiers CCS 2023 笔记 本文介绍了一种名为 TsuKing 的新型 DNS 放大攻击。与以前利用单个DNS解析器的攻击不同&#xff0c;TsuKing协调多个…

Linux-实现小型日志系统

目录 一.日志 二.实现任意个数元素求和 三.编写一个日志函数 1.设置日志等级 2.设置日志时间 3.设置日志的打印格式 4.将日志的内容输出到文件 一.日志 日志等级&#xff0c;日志时间&#xff0c;日志内容&#xff0c;文件的名称和行号 日志等级…

写论文焦虑?No,免费AI写作大师来帮你

先来看1分钟的视频&#xff0c;对于要写论文的你来说&#xff0c;绝对有所值&#xff01; 还在为写论文焦虑&#xff1f;免费AI写作大师来帮你三步搞定 第一步&#xff1a;输入关键信息 第二步&#xff1a;生成大纲 稍等片刻后&#xff0c;专业大纲生成&#xff08;由于举例&am…

Java的第二十一章:网络通信

网络程序设计基础 网络程序设计编写的是与其他计算机进行通信的程序。Java 已经将网络程序所需要的元素封装成不同的类&#xff0c;用户只要创建这些类的对象&#xff0c;使用相应的方法&#xff0c;即使不具备有关的网络支持&#xff0c;也可以编写出高质量的网络通信程序。 …

二叉树的基本概念(详解)

树的定义 树是一种非线性数据结构&#xff0c;由n&#xff08;n>1&#xff09;个节点以及n-1条边组成&#xff0c;其中有且仅有一个节点作为根节点。树的定义具有以下特点&#xff1a; 每个节点具有零个或多个子节点。除了根节点外&#xff0c;每个节点有且仅有一个父节点…

【Pytorch使用自制数据集,Dataloader】

数据集结构 话不多说&#xff0c;直接上核心代码 myDataset.py from collections import Counter from torch.utils.data import Dataset import os from PIL import Imageclass MyDataset(Dataset):"""读取自制的数据集args:- image_dir: 图片的地址- labe…

【ETL】Kettle清洗任务异常提醒,Spoon作业异常通知

清洗作业如果挂在第三方任务平台或比较多的任务&#xff0c;执行失败无法跟踪&#xff0c;需要给任务添加异常提醒&#xff0c;这里用钉钉的群消息机器人。 钉钉机器人文档 自定义机器人接入 - 钉钉开放平台 作业示例 通过请求触发告警消息

谈一谈C++的类对象的存储方式

在C的类中&#xff0c;有成员变量和成员函数。当类经过实例化后&#xff0c;便有了类对象&#xff0c;C示例对象中的成员变量和成员函数是分开存储的。 成员变量 : 普通成员变量 : 在 对象 指针指向的内存中存储 , 存储方式与 C 语言中的 struct 结构体 存储变量的 内存结布局 …

Python图像处理利器解密:Pillow库使用指南

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 引言 Pillow库是Python编程中用于图像处理的重要工具。作为Python Imaging Library&#xff08;PIL&#xff09;的一个分支&#xff0c;Pillow库提供了丰富的功能和易用的API&#xff0c;用于处理图像的各种操作…

基于SpringBoot的校园互助网站

简介 本系统分为三个角色&#xff0c;分别是普通用户和管理员、以及超级管理员&#xff0c;主要的功能模块有注册、登录、物品代购、快递代取、话题管理、任务管理、反馈管理、投诉管理、订单管理等功能模块。 项目 数据库 首页 登录 新增反馈 发布话题 发布任务 接单 我要投诉…

华为无线配置模板 一

华为无线配置模板 一 拓扑图1.配置SwitchA和AC&#xff0c;使AP与AC之间能够传输CAPWAP报文2.配置AC作为DHCP服务器&#xff0c;为STA和AP分配IP地址3.配置AP上线4.配置WLAN业务参数5.验证配置结果 拓扑图 采用如下的思路配置小型网络的WLAN基本业务&#xff1a;1.配置AP、AC、…

接口自动化测试过程中怎么处理接口依赖?

面试的时候经常会被问到在接口自动化测试过程中怎么处理接口依赖&#xff1f; 首先我们要搞清楚什么是接口依赖。 01. 什么是接口依赖 接口依赖指的是&#xff0c;在接口测试的过程中一个接口的测试经常需要依赖另一个或多个接口成功请求后的返回数据。 那怎么处理呢&#x…

2023年【A特种设备相关管理(锅炉压力容器压力管道)】考试内容及A特种设备相关管理(锅炉压力容器压力管道)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试内容根据新A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试大纲要求&#xff0c;安全生产模拟考试一点通将A特种设备相关管理…

Rust的From与Into Trait

Into的本质是调用了From Trait 的方法。 From是底层的方法&#xff0c;把From实现了&#xff0c;Into的实现&#xff0c;编译器会自动根据From Trait生成Into Trait的代码 编译器自动类型推导出Into Trait的U的类型&#xff0c;调用了U类型的From的方法&#xff0c;实现其他类…

【多线程】-- 12 线程协作之生产者消费者问题及解决办法

多线程 9 线程协作 “生产者消费者问题” ——并非二十三种设计模式之一 9.1 生产者消费者问题 “线程通信” 应用场景&#xff1a;生产者和消费者问题 假设仓库中只能存放一件产品&#xff0c;生产者将生产出来的产品放入仓库&#xff0c;消费者将仓库中产品取走消费如果…

JDK8升级11常见问题

JDK8升级11常见问题 1. 使用rt.jar/jce.jar情况 原代码&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><targe…

vue el-select多选封装及使用

使用了Element UI库中的el-select和el-option组件来构建多选下拉框。同时&#xff0c;也包含了一个el-input组件用于过滤搜索选择项&#xff0c;以及el-checkbox-group和el-checkbox组件用于显示多选项。 创建组件index.vue (src/common-ui/selectMultiple/index.vue) <tem…

生成式 AI 应用落地小结:高估的模型能力,低估的工程实施

虽然 ChatGPT 已经诞生了一周年&#xff0c;但是大量的人依旧对于生成式 AI 没有足够的认识。在研发领域&#xff0c;Thoughtworks 一直在与不同的大型企业合作&#xff0c;保持开放性的探索。 在我负责的 Thoughtworks 开源社区&#xff0c;我们与外部的几家大型企业一起探索和…