SpringAOP-概述+配置文件的形式实现

news2024/9/25 7:18:29

2.1AOP概述

什么是AOP?

AOP全称Aspect Oriented Programming,翻译过来就是:面向切面编程。

  • AOP是一种编程的规范
  • AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
  • 通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

总结:AOP就是在不修改源代码的前提下,对程序的代码进行增强。

AOP优势

AOP是在运行期间在不修改源代码的情况下对代码进行增强的

AOP的底层原理

jdk动态代理技术:

1.为接口创建代理类的字节码文件

2.使用ClassLoader将字节码文件加载到jvm

3.创建代理类的实现对象执行目标方法

2.2 Spring的AOP技术-配置文件的形式

2.2.1 AOP相关术语

Joinpoint(连接点) 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点

Pointcut(切入点) -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义

Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Target(目标对象)-- 代理的目标对象

Weaving(织入)-- 是指把增强应用到目标对象来创建新的代理对象的过程

Proxy(代理)-- 一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面)-- 是切入点和通知的结合,以后咱们自己来编写和配置的

2.2.2 AOP配置文件的方式

创建项目,并导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Spring03</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <!--有单元测试的环境,Spring5版本,Junit4.12版本-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
        <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!-- Spring整合Junit测试的jar包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <!-- AOP联盟 -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- Spring Aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!-- aspectj -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.3</version>
        </dependency>

    </dependencies>

</project>

        创建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.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">

</beans>

创建包的结构

编写具体的接口和实现类

接口

/**
 * 用户模块业务层的接口
 */
public interface UserService {
    public void save();
}

接口的实现类

/**
 * 用户模块业务层实现业务类
 * 实现保存方法
 */
public class UserServiceImpl implements UserService{
    @Override
    public void save() {
        System.out.println("保存方法执行了!!!");
    }
}
<!--  将UserServiceImpl交给Spring去管理 -->
    <bean id="userService" class="com.qcby.demo1.UserServiceImpl"/>
    <!--  将切面类交给Spring去管理  -->
    <bean id="myXmlAspect" class="com.qcby.demo1.MyXmlAspect"/>
    <!--  AOP的配置  -->
    <!--配置aop的增强-->
    <aop:config>
<!-- MyXmlAspect被定义为切面类 -->
<!-- 配置切面=切入点+通知 -->
        <aop:aspect ref="myXmlAspect">
            <!-- execution() 固定写法
                 public     可以省略不写
                 方法的返回值类型   int String等 可以写* 但是不能不写
                 包名+类名      不能省略不写,可以写*
                 方法名

             -->
<!--            <aop:before method="log" pointcut="execution(public void com.qcby.demo1.UserServiceImpl.save())"/>-->
            <aop:after-returning method="log" pointcut="execution(public void com.qcby.demo1.UserServiceImpl.save())"/>
        </aop:aspect>
    </aop:config>

        切面类

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

    public void log(){
        //发送短信、记录日志、事务管理
        System.out.println("执行增强方法");
    }

}

        在配置文件中完成aop的配置

<!--  AOP的配置  -->
    <!--配置aop的增强-->
    <aop:config>
<!-- MyXmlAspect被定义为切面类 -->
<!-- 配置切面=切入点+通知 -->
        <aop:aspect ref="myXmlAspect">
            <!-- execution() 固定写法
                 public     可以省略不写
                 方法的返回值类型   int String等 可以写* 但是不能不写
                 包名+类名      不能省略不写,可以写*
                 方法名

             -->
<!--            <aop:before method="log" pointcut="execution(public void com.qcby.demo1.UserServiceImpl.save())"/>-->
            <aop:after-returning method="log" pointcut="execution(public void com.qcby.demo1.UserServiceImpl.save())"/>
        </aop:aspect>
    </aop:config>

        编写测试用例

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
public class Demo1 {

    @Autowired
    private UserService userService;
    @Test
    public void run1(){
        userService.save();
    }

}

输出结果

2.2.3 切点表达式的写法

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

切入点表达式的格式如下:

· execution([修饰符] 返回值类型 包名.类名.方法名(参数))

· 修饰符可以省略不写,不是必须要出现的。

· 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。

· 包名例如:com.tx.demo3.BookDaoImpl

o 首先com是不能省略不写的,但是可以使用 * 代替

o 中间的包名可以使用 * 号代替

o 如果想省略中间的包名可以使用 ..

· 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl

· 方法也可以使用 * 号代替

参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用

2.3.4 通知的类型

1. 前置通知 目标方法执行前,进行增强。

2. 最终通知 目标方法执行成功或者失败,进行增强。

3. 后置通知 目标方法执行成功后,进行增强。

4. 异常通知 目标方法执行失败后,进行增强。

5. 环绕通知 目标方法执行前后,都可以进行增强。目标对象的方法需要手动执行。

<!--配置AOP的增强-->    
<aop:config>        
<!--配置切面 = 切入点 + 通知组成-->        
<aop:aspect ref="myXmlAspect">                      
 <!-- AOP的通知类型
 前置通知:目标方法执行前,进行增强。-->
 aop:before method="log" pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />                   
  最终通知:目标方法执行成功或者失败,进行增强。                        
  <aop:after method="log" pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />                    
  后置通知:目标方法执行成功后,进行增强。                        
  <aop:after-returning method="log" pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />                    
  异常通知:目标方法执行失败后,进行增强。                        
  <aop:after-throwing method="log" pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />                    
  环绕通知:目标方法执行前后,都可以进行增强。目标对象的方法需要手动执行。         
  <aop:around method="aroundLog" pointcut="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))" />​        
  </aop:aspect>   
 </aop:config>

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

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

相关文章

投资组合理论中的资本资产定价模型(CAPM)和套利定价理论(APT)的实现案例

一&#xff1a;资本资产定价模型&#xff08;CAPM&#xff09; 资本资产定价模型&#xff08;Capital Asset Pricing Model&#xff0c;简称CAPM&#xff09;是金融学中一个重要的理论模型&#xff0c;用于估算一个投资的预期回报率&#xff0c;并确定投资的风险与预期回报之间…

前端面试题每日一练,测测你对JavaScript生成器和 Array.from 的理解

今天的挑战题目涉及到JavaScript中的生成器函数 (Generator) 和 Array.from 方法的结合使用。我们将利用生成器生成斐波那契数列&#xff0c;并通过 Array.from 创建一个包含前几个斐波那契数的数组。让我们一步步解析这段代码&#xff0c;看看它会输出什么以及为什么。 代码解…

抽奖系统PHP源码开源二开版带完整后台

该程序可以作为活动氛围活动气氛的烘托作用&#xff0c;活动游戏而已&#xff01; 抽奖系统源码是一个以php MySQL进行开发的手机抽奖系统源码。用途&#xff1a;适合做推广营销、直播、粉丝抽奖。 功能介绍&#xff1a; 1、后台可以设置每个抽奖用户的抽奖次数,后台添加设置…

四川财谷通信息技术有限公司引领抖音小店新风尚

在当今这个数字化时代&#xff0c;电子商务的浪潮以前所未有的速度席卷全球&#xff0c;而短视频平台抖音凭借其庞大的用户基数和强大的流量变现能力&#xff0c;成为了众多商家竞相入驻的新蓝海。在这片充满机遇与挑战的海洋中&#xff0c;四川财谷通信息技术有限公司以其敏锐…

模型 福格行为

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。BMAP 1 福格行为的应用 1.1 基于福格行为模型的儿童教育应用设计 随着移动互联网的普及&#xff0c;儿童教育应用迅速发展&#xff0c;如何设计出既吸引儿童又能积极促进学习的教育应用成为设计者关…

景芯SoC A72实战反馈

先说结论&#xff1a; 内容非常全面&#xff0c;讲解到位&#xff0c;会有专门的工程师一对一答疑&#xff0c;整个项目跑下来提升非常大&#xff0c;绝对物超所值&#xff01; 一些细节&#xff1a; 本人微电子专业研一在读&#xff0c;有过两次简单的数字芯片流片经历&…

IO进程day04(进程)

目录 进程 1》什么是进程 1> 概念 2> 特点 3> 进程段 4> 进程分类 5> 进程状态 6> 进程状态切换图 7> 进程相关命令 <补充>优先级调度 2》进程函数接口 1> 创建进程 fork() 2> 回收资源 3> 结束进程 4> 获取进程号 3》exe…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 08网络自动化

云原生数据中心和老一代数据中心不同之处在于其核心概念是聚焦于高效运营。网络自动化就是达到此目标的关键因素。 要达到此目的&#xff0c;本章要解决诸如下述的一些问题&#xff1a; 什么是网络自动化以及为什么我们在乎它?为了学习网络自动化&#xff0c;我需要学习编程…

栈OJ题——栈的压入、弹出序列

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 栈的压入、弹出序列 题目描述&#xff1a;给定两个整型数组&#xff0c;判断数组2是否是数组1的某一个出栈顺序。该题默认可以边入栈边出栈。 二、解题思路 三、解题代码 但是&#xff0c;上述解题代码中还存在一…

HCIP第一天作业

要求&#xff1a;R1-R2-R3-R4-R5 RIP 100 运行版本2 R6-R7 RIP 200 运行版本1 1.使用合理IP地址规划网络&#xff0c;各自创建环回接口 2.R1创建环回 172.16.1.1/24 172.16.2.1/24 172.16.3.1/24 3.要求R3使用R2访问R1环回 4.减少路由条目数量&#xff0c;R1-R2之间增…

Echarts栅格进度条装饰实现

如下图&#xff0c;如果你的业务需要这么一个饼图&#xff0c;你单纯借助echarts是实现不了如图效果的&#xff0c;你需要借助dom操作&#xff0c;合svg的配合才能实现。 首先饼图部分结束echarts,实现以及通过配置实现你想要的效果。 中间的文字百分比计算需要自己计算&#…

springboot3.x入门系列【5】支持unix sock 套接字服务

目录 一、简介 二、springBoot3.x 套接字的支持 1. 环境要求 2. springboot内置tomcat 2.1 支持unix 设置 unixDomainSocketPath 2.2 windows 下unix服务测试 3. springboot外置tomcat 3.1 tomcat 配置unix socket 套接字 3.2 启动tomcat 服务 3.3 nginx 支持unix…

python中传递任意数量的实参

有时候&#xff0c;你预先不知道函数需要接受多少个实参&#xff0c;好在Python允许函数从调用语句中收集任意数量的实参。 一个*是元组&#xff0c;两个是字典。

交换机自动化巡检(H3C)

目的:通过python实现全自动化交换机巡检&#xff08;每周五下午五点进行自动化巡检&#xff09; 1、环境&#xff1a; 系统&#xff1a;windows10 工具&#xff1a;python-3.11.2&#xff08;自行安装&#xff09; 工具&#xff1a;PyCharm Community Edition 2022.3.3&…

Vue使用v-model收集各种表单数据、过滤器

目录 1. 使用v-model收集各种表单数据2. 日期格式化3. 过滤器 1. 使用v-model收集各种表单数据 若<input type“text”/>&#xff0c;则v-model收集的是value值&#xff0c;用户输入的就是value值若<input type“radio”/>&#xff0c;则v-model收集的是value值&a…

【Linux系列】du命令详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【线程池】

什么是线程池&#xff1f; 线程池是一个可以复用线程的技术。简单来说&#xff0c;线程池是一种基于池化技术的思想来管理线程的技术&#xff0c;旨在减少线程的创建和销毁次数&#xff0c;提高系统的响应速度和吞吐量。它预先创建了一定数量的线程&#xff0c;并将这些线程放…

MySQL高可用性实践指南

一 、Mysql 在服务器中的部署方法 1、安装依赖性 yum install libtirpc-devel-0.2.4-0.16.el7.x86_64.rpm -y yum install ncurses-devel.x86_64 -y yum install gcc-c -y yum install openssl-devel -y yum install cmake -y 2、下载并解压源码包 tar zxf mysql-boost-5.7…

十年热爱,小鹏汽车开启AI新篇章

“每一台小鹏汽车&#xff0c;都是同级别智能的天花板。”在8月27日的小鹏10年热爱之夜暨小鹏MONA M03上市发布会上&#xff0c;小鹏汽车董事长、CEO何小鹏不无自豪地表示。 对于小鹏汽车来说&#xff0c;此次发布会有着非凡的意义&#xff0c;因为它不仅是对小鹏汽车过去十年辉…

前端用js发送邮箱 前端发送邮箱

前端发送邮箱 安装包依赖邮箱授权码demo eg:picture页面发送内容有效接受效果 code参考别人写的code 说明 安装包依赖 yarn add nodemailernodemailer官网 邮箱授权码 邮箱授权码: 邮箱授权码需要开通&#xff0c;以QQ邮箱为例&#xff0c;其它大同小异 demo eg: picture…