Spring框架(下半部分 -AOP)

news2024/9/24 5:26:04

1.2 AOP相关的概念

1.2.1 AOP的概述

什么是AOP的技术?
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

  • AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
  • AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
  • 通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
    AOP:面向切面编程.(思想.—解决OOP遇到一些问题)
    AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
    为什么要学习AOP,可以在不修改源代码的前提下,对程序进行增强!!

1.2.2 AOP的优势

运行期间,不修改源代码的情况下对已有的方法进行增强
优势

  1. 减少重复的代码
  2. 提供开发的效率
  3. 维护方便

1.2.3 AOP的底层原理

  • JDK的动态代理技术
    1. 为接口创建代理类的字节码文件
    2. 使用ClassLoader将字节码文件加载到JVM
    3. 创建代理类实例对象,执行对象的目标方法
  • cglib代理技术

1.3 Spring的AOP技术-配置文件方式

1.3.1 AOP相关的术语

  • Joinpoint(连接点) 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
  • Pointcut(切入点) – 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
  • Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
  • Target(目标对象)-- 代理的目标对象
  • Weaving(织入)-- 是指把增强应用到目标对象来创建新的代理对象的过程
  • Proxy(代理)-- 一个类被AOP织入增强后,就产生一个结果代理类
  • Aspect(切面)-- 是切入点和通知的结合,以后咱们自己来编写和配置的

1.3.2 切入点的表达式

再配置切入点的时候,需要定义表达式,具体展开如下:
切入点表达式的格式如下:

  • execution([修饰符] 返回值类型 包名.类名.方法名(参数))
  • 修饰符可以省略不写,不是必须要出现的。
  • 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
  • 包名例如:com.tx.demo3.BookDaoImpl
  • 首先com是不能省略不写的,但是可以使用 * 代替
  • 中间的包名可以使用 * 号代替
  • 如果想省略中间的包名可以使用 …
  • 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
  • 方法也可以使用 * 号代替
  • 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 …

1.3.3 AOP的通知类型

  1. 前置通知 目标方法执行前,进行增强。
  2. 最终通知 目标方法执行成功或者失败,进行增强。
  3. 后置通知 目标方法执行成功后,进行增强。
  4. 异常通知 目标方法执行失败后,进行增强。
  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.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id = "us" class = "com.qcby.demo1.UserServiceImpl"/>

    <bean id = "myXmlAspect" class = "com.qcby.demo1.MyXmlAspect"/>

    <aop:config>
        <aop:aspect ref = "myXmlAspect">
            <!--前置通知:UserServiceImpl的save方法执行前,会增强-->
            <aop:before method="log" pointcut="execution(public * com.qcby.demo1.UserServiceImpl.save())"/>

            <!--后置通知-->
            <aop:after-returning method="afterReturning" pointcut="execution(public * com.qcby.demo1.UserServiceImpl.save())"/>

            <!--异常通知-->
            <aop:after-throwing method="afterThrowing" pointcut="execution(public * com.qcby.demo1.UserServiceImpl.save())"/>

            <!--最终通知-->
            <aop:after method="after" pointcut="execution(public * com.qcby.demo1.UserServiceImpl.save())"/>
        </aop:aspect>
    </aop:config>

</beans>

切面类MyXmlAspect.java:

package com.qcby.demo1;

/**
 *
 *自定义切面类 = 切入点(表达式) + 通知(增强的代码)
 */
public class MyXmlAspect {

    /**
     * 前置通知
     */
    public void log(){
        // 发送手机短信
        // 发送邮件/记录日志/事务管理
        System.out.println("前置增强的方法执行了...");
    }

    /**
     * 最终通知
     */
    public void after(){
        System.out.println("最终通知的方法...");
    }

    /**
     * 后置通知
     */
    public void afterReturning(){
        System.out.println("后置通知的方法...");
    }

    /**
     * 异常通知
     */
    public void afterThrowing(){
        System.out.println("异常通知的方法...");
    }
}

运行结果:
![[Pasted image 20240120203915.png]]

环绕通知:

<!--环绕通知-->
            <aop:around method="around" pointcut="execution(public * com.qcby.demo1.UserServiceImpl.save())"/>

/**
* 环绕通知
*/
public void around(ProceedingJoinPoint joinPoint){
	try {
		// 前置与后置,相当于开始事务与提交事务
		System.out.println("前置增强的方法执行了...");
		// 在这里需要手动执行目标对象的方法
		joinPoint.proceed();
		System.out.println("后置通知的方法...");
	} catch (Throwable  throwable){
		throwable.printStackTrace();
		// 出现异常
		System.out.println("异常通知的方法...");
	} finally {
		// 无论如何都要执行
		System.out.println("最终通知的方法...");
	}
}

1.4 Spring的AOP技术-注解方式

1.4.1 注解+配置文件的方式

MyAnnoAspect.java:

package com.qcby.demo2;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 切面类
 */

@Component // 普通类交给Spring管理
@Aspect // 切面类
public class MyAnnoAspect {

    /**
     * 通知的方法
     *  @Before
     *  @AfterReturning
     *  @AfterThrowing
     *  @After()
     *  @Around()
     */
    @Before("execution(public void com.qcby.demo2.OrderServiceImpl.save())")
    public void log(){
        System.out.println("前置通知的方法...");
    }
}

beans_demo2.xml:

<?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.xsd
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--开启注解扫描-->
    <context:component-scan base-package="com.qcby.demo2"/>
    <!--开启自动代理-->
    <aop:aspectj-autoproxy/>
</beans>

DemoTest2.java:

package com.qcby.demo;

import com.qcby.demo2.OederService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)

// 配置文 classpath
@ContextConfiguration("classpath:beans_demo2.xml")

// 配置类 classes
//@ContextConfiguration(classes=SpringConfig.class)
public class DemoTest2 {
    @Autowired
    private OederService oederService;
    /**
     * 测试
     * 注解+配置文件
     */
    @Test
    public void run(){
        oederService.save();
    }
}

1.4.2 纯注解的方式

配置类SpringConfig.java:

package com.qcby.demo2;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration // 配置类
@ComponentScan(value = "com.qcby.demo2") // 扫描包
@EnableAspectJAutoProxy   // 开启自动代理 == <aop:aspectj-autoproxy />
public class SpringConfig {
}

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

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

相关文章

【开源-土拨鼠充电系统】鸿蒙 HarmonyOS 4.0 App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在Gitee或GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍Gitee开源项目地址&#x1f449;&#xff1a;https://gitee.com/cheinlu/groundhog-charging…

多维时序 | MATLAB实现BiTCN-selfAttention自注意力机制结合双向时间卷积神经网络多变量时间序列预测

多维时序 | MATLAB实现BiTCN-selfAttention自注意力机制结合双向时间卷积神经网络多变量时间序列预测 目录 多维时序 | MATLAB实现BiTCN-selfAttention自注意力机制结合双向时间卷积神经网络多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.M…

深度学习_20_卷积中的填充与步幅

如果图片本身比较小&#xff0c;卷积之后输出也会很小&#xff0c;那么可以在图片与卷积核相乘之前先填充一下&#xff0c;让输出为预期大小 一般填充后输入&#xff0c;输出相同 当图片比较大的时候&#xff0c;如果利用卷积核去得到我们想要的大小的话&#xff0c;得用到多层…

Linux虚拟主机如何快速卸载一键安装的网站程序

接到一位用户发送的请求帮助&#xff0c;想要卸载通过Softaculous一键安装的网站程序&#xff0c;但是没有找到地方&#xff0c;根据与该用户的沟通得知是一个小白用户&#xff0c;想要自己搭建一个博客类的网站&#xff0c;了解到Hostease 有适合新用户并且带管理面板的产品Li…

Nginx:部署及配置详解(linux)

Nginx&#xff1a;部署及配置详解&#xff08;linux&#xff09; 1、nginx简介2、安装编译工具及库文件3、安装 pcre4、nginx安装5、nginx配置文件nginx.conf组成6、nginx配置实例-反向代理7、nginx 配置实例-负载均衡 &#x1f496;The Begin&#x1f496;点点关注&#xff0c…

代码随想录算法训练营第day53|1143.最长公共子序列 、 1035.不相交的线、 53. 最大子序和 动态规划

目录 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 1143.最长公共子序列 力扣题目链接(opens new window) 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原…

【嵌入式——QT】QT Charts

【嵌入式——QT】QT Charts 概述Qt提供的坐标轴类QChartQLineSeriesQValueAxis常见图表及用到的序列类图示代码示例 概述 QT Charts模块是一组易于使用的图表组件&#xff0c;它基于Qt的Graphics View架构&#xff0c;其核心组件是QChartView和QChart&#xff0c;QChartView父…

【傻瓜文档】鼎利测试软件Pilot Pioneer-② 数据分析与处理功能

数据分析与处理功能 数据导入、解码 ① 导入数据 两种方式: 添加新数据导入历史数据不需要的数据可以移除 ② 数据解码 正式格式的数据可以重解码,例如Rcu、dcf等等,尽量选择正式数据。 两种方式: 选中数据,右键选择重解码双击信令重解码后的文件会生成为DitIB的文件…

第二节 动态面板使用实例操作

1、使用元件库 2、使用添加元件库 1.添加外部元件库 2.自做元件库 保存为*.rplib文件&#xff0c;就可以给其他项目使用了。 3、制作母板 1、新建模版 2、导入旧模版 此操作主要用于想使用原型中已经做好母版&#xff0c;有时直接粘贴又粘贴不成功&#xff0c;需要按下面方式…

MQTT和Modbus的物联网网关协议区别分析

MQTT和Modbus的物联网网关协议区别分析 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;与Modbus是两种广泛应用在物联网环境中的通信协议&#xff0c;它们各自具有独特的优势和适用场景&#xff0c;下面将从多个维度对这两种网关协议进行详细区别分析。 首…

ShardingSphere+JPA+Druid实现分表操作

要在SpringBoot项目中实现分表操作&#xff0c;本文使用的是ShardingSphereJPADruid实现。过程中出现问题记录一下。 准备MySQL数据库表 这里准备的是一张主表test_cost&#xff0c;两张从表test_cost_0和test_cost_1&#xff0c;结构需要相同&#xff0c;主表只是声明了表结构…

3.21 day2 QT

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 要求: 1.需要使用Ui界面文件进行界面设计 2.ui界面上的组件相关设置&#xff0c;通过代码实现 3需要添加适当的动图

【C++】—— 装饰器模式

目录 &#xff08;一&#xff09;什么是装饰器模式 &#xff08;二&#xff09;为什么要使用装饰器模式 &#xff08;三&#xff09;装饰器模式的实现步奏 &#xff08;四&#xff09;代码示例 &#xff08;五&#xff09;装饰器模式优缺点 &#xff08;一&#xff09;什么…

解决GNURadio自定义C++ OOT块-导入块时报错问题

文章目录 前言一、问题描述二、解决方法1、安装依赖2、配置环境变量3、重新编译及安装三、结果1、添加结果2、运行结果前言 本文记录在 GNURadio 自定义 C++ OOT 块后导入块时报错 AttributeError: module myModule has no attribute multDivSelect。 一、问题描述 参考官方教…

css使用变量

vue3单文件SFC新特性在css里可以使用变量&#xff0c;具体使用如下&#xff1a; <template><div class"home-view"><span>测试</span><p>测试2</p></div> </template><script setup lang"ts"> imp…

Web Service接口测试

Web service 接口测试 一. web Service概念 Web service使用与平台和编程语言无关的方式进行通讯的一项技术, web service 是一个接口, 他描述了一组可以在网络上通过标准的XML消息传递访问的操作,它基于xml语言协议来描述要执行的操作或者要与另外一个web 服务交换数据, 一组…

Leetcode 994. 腐烂的橘子

心路历程&#xff1a; 一开始以为和刚做过的岛屿问题很像&#xff0c;只不过是把岛屿问题换成BFS去做&#xff0c;然后再加上一些计数的规则。结果做完后发现只能通过一半左右的测试用例&#xff0c;发现有一个逻辑错误在于&#xff0c;当腐烂的橘子位于两端时&#xff0c;可以…

代码随想录算法训练营第day25|216.组合总和III、 17.电话号码的字母组合

216.组合总和III 力扣题目链接 (opens new window) 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数&#xff0c;并且每种组合中不存在重复的数字。 说明&#xff1a; 所有数字都是正整数。解集不能包含重复的组合。 示例 1: 输入: k 3, n 7 输…

转置卷积(transposed-conv)

一、什么是转置卷积 1、转置卷积的背景 通常&#xff0c;对图像进行多次卷积运算后&#xff0c;特征图的尺寸会不断缩小。而对于某些特定任务 (如图像分割和图像生成等)&#xff0c;需将图像恢复到原尺寸再操作。这个将图像由小分辨率映射到大分辨率的尺寸恢复操作&#xff0c…

el-table的border属性失效问题解决方案

目录 问题&#xff1a; 使用的代码&#xff1a; 官方文档的说明&#xff1a; 可能的问题所在&#xff1a; 关于使用了作用域插槽&#xff1a; a.自定义内容的样式覆盖&#xff1a; b.表格结构的改变&#xff1a; 解决方案&#xff1a; 通过css样式解决&#xff1a; 下面…