Spring中的AOP

2023-11-15

1.概述

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP(面向切面编程)_百度百科

2.相关术语

Joinpoint(连接点):

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

Pointcut(切入点):

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

Advice(通知/增强):

所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。

Introduction(引介):

引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。

Target(目标对象):

代理的目标对象。 

Weaving(织入):  

是指把增强应用到目标对象来创建新的代理对象的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。

一个连接点可以同时匹配多个切点,而切点所对应的增强在连接点上织入顺序的规则是这样的:
如果在同一个切面类中声明的增强,则按照增强在切面类中定义的顺序进行织入;
如果增强位于不同的切面类中,并且这些切面类都实现了org.springframework.core.Ordered接口,则由 Ordered 方法的顺序号决定(顺序号小的先织入);
如果增强位于不同的切面类中,但这些切面类没有实现org.springframework.core.Ordered 接口,织入的顺序是不确定的。

Proxy(代理):

 一个类被 AOP 织入增强后,就产生一个结果代理类。

Aspect(切面):

是切入点和通知(引介)的结合。

Advisor

这个概念是从 Spring 1.2的 AOP 支持中提出的,一个 Advisor 相当于一个小型的切面,不同的是它只有一个通知(Advice),Advisor 在事务管理里面会经常遇到。

3.代码示例

1、创建项目并导入jar包

 2、接口与核心类;

public interface BookService {
    int save(int n);
    int del();
    int update();
    void find();
}

创建BookServiceImpl类,完成核心功能操作;

/**
 * 核心类
 */

public class BookServiceImpl implements BookService {
    @Override
    public int save(int n) {
        System.out.println("添加");
        return 1;
    }

    @Override
    public int del() {
        System.out.println("删除");
        return 1;
    }

    @Override
    public int update() {
        System.out.println("修改");
        return 1;
    }

    @Override
    public void find() {
        System.out.println("查询");
    }
}

 3、创建Logger类,用来做功能的增强类;

/**
 * 增强类
 */
public class Loger {
    public void check(){
        System.out.println("前置通知/增强:执行系统的权限验证");
    }
    public void logPrint(){
        System.out.println("后置通知/增强:执行日志的打印");
    }
    public void exception(){
        System.out.println("异常通知/增强:做出异常的处理");
    }
    public void destroy(){
        System.out.println("最终通知/增强:资源的释放");
    }
}

4、在的spring.xml中开始进行AOP的配置;

4.1、首先把核心类和增强类的bean配置到IOC的容器中

4.2、使用<aop:config>标签在进行AOP的配置,先通过aop:aspect标签标明谁是增强类。然后在标签中进行aop:before(前置)、aop:after-returning(后置)、aop:after-throwing(异常)、aop:after(最终)的配置,让增强类的某个方法对核心功能类的某一类方法进行功能增强。

<?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">

    <!--1.把所有类的对象交给IOC容器进行管理-->
    <bean id="loger" class="com.zhan.advice.Loger"/>
    <bean id="bookService" class="com.zhan.service.impl.BookServiceImpl"/>

    <!--2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法-->
    <aop:config>
        <!--配置增强类-->
        <aop:aspect id="log" ref="loger">
            <aop:before method="check" pointcut="execution(* *..BookService.*(..))"/>
            <aop:after-returning method="logPrint" pointcut="execution(* *..BookService.*(..))"/>
            <aop:after-throwing method="exception" pointcut="execution(* *..BookService.*(..))"/>
            <aop:after method="destroy" pointcut="execution(* *..BookService.*(..))"/>
        </aop:aspect>

    </aop:config>
    
</beans>

 5、测试类测试BookServiceImpl的方法是否被增强;

public class Test01 {
    @Test
    public void test01(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        BookService bookService = context.getBean(BookService.class);
        bookService.save(5);
    }
}

日志信息

 

4.环绕通知

环绕通知是一种提供自由灵活对核心类方法进行增强的操作手段,首先还是在spring.xml中配置环绕通知。包含了前置、后置、异常、最终通知;

通过ProceedingJoinPoint的实现类对象(spring框架会创建)获取要增强的那个类的方法参数、执行方法、获得方法返回值。然后在方法执行之前的操作就是前置通知、在方法执行后的操作就是后置通知、在异常处理中的操作就是异常通知、在finally中执行的操作就是最终通知。

1、配置环绕通知

<aop:config>
        <!--配置增强类-->
        <aop:aspect id="log" ref="loger">
            <aop:around method="around" pointcut="execution(* *..BookService.*(..))"/>
        </aop:aspect>
    </aop:config>

 2、在增强类中完善环绕通知的方法,定义一个ProceedingJoinPoint接口对象作为方法参数,且方法返回值是Object。

public class Loger {
    public void check(){
        System.out.println("前置通知/增强:执行系统的权限验证");
    }
    public void logPrint(){
        System.out.println("后置通知/增强:执行日志的打印");
    }
    public void exception(){
        System.out.println("异常通知/增强:做出异常的处理");
    }
    public void destroy(){
        System.out.println("最终通知/增强:资源的释放");
    }

    public Object around(ProceedingJoinPoint pjp){
        try{
            //前置增强
            System.out.println("环绕通知---前置增强");
            //通过ProceedingJoinPoint完成代理对象的方法调用
            Object result = null;//定义返回值变量
            //获取参数列表
            Object[] args = pjp.getArgs();
            //核心类方法的执行
            result= pjp.proceed(args);
            //后置增强
            System.out.println("环绕通知---后置增强");
            return result;

        }catch(Throwable e){
            //异常增强
            System.out.println("环绕通知---异常增强");
            throw new RuntimeException();
        }finally {
            //异常增强
            System.out.println("环绕通知---最终增强");
        }
    }
}

5.基于注解的Aop

1、创建项目并导入jar包

1、配置注解的扫描,同时配置开启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: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">

    <!--1.扫描component及同名注解-->
    <context:component-scan base-package="com.zhan"/>
    <!--2.开启AOP注解支持-->
    <aop:aspectj-autoproxy/>

</beans>

2、接口与核心类;

public interface BookService {
    int save(int n);
    int del();
    int update();
    void find();
}

创建BookServiceImpl类实现接口,完成核心功能操作;定义IOC容器的bean标签使用注解替换 

@Service
public class BookServiceImpl implements BookService {
    @Override
    public int save(int n) {
        System.out.println("添加");
//        int a =5/0;
        return 1;
    }

    @Override
    public int del() {
        System.out.println("删除");
        return 1;
    }

    @Override
    public int update() {
        System.out.println("修改");
        return 1;
    }

    @Override
    public void find() {
        System.out.println("查询");
    }
}

3、创建Logger类,用来做功能的增强类;

@Component:标注Spring管理的Bean,表示将此类标记为Spring容器中的一个Bean。 

@Aspect:告诉spring框架该类是一个切面类,用来做功能的增强

@Before:前置通知

@AfterReturning:后置通知

@AfterThrowing:异常通知

@After:最终通知

这四个注解替代,同时在注解中定义要增强那个包中那个类的那个方法,且使用表达式表示。

@Component
@Aspect
public class Loger {
    @Before("execution(* *..BookService.*(..))")
    public void check(){
        System.out.println("前置通知/增强:执行系统的权限验证");
    }
    @AfterReturning("execution(* *..BookService.*(..))")
    public void logPrint(){
        System.out.println("后置通知/增强:执行日志的打印");
    }
    @AfterThrowing("execution(* *..BookService.*(..))")
    public void exception(){
        System.out.println("异常通知/增强:做出异常的处理");
    }
    @After("execution(* *..BookService.*(..))")
    public void destroy(){
        System.out.println("最终通知/增强:资源的释放");
    }
    //@Around("execution(* *..BookService.*(..))")
    public Object around(ProceedingJoinPoint pjp){
        try{
            //前置增强
            System.out.println("环绕通知---前置增强");
            //通过ProceedingJoinPoint完成代理对象的方法调用
            Object result = null;//定义返回值变量
            //获取参数列表
            Object[] args = pjp.getArgs();
            //核心类方法的执行
            result= pjp.proceed(args);
            //后置增强
            System.out.println("环绕通知---后置增强");
            return result;
        }catch(Throwable e){
            //异常增强
            System.out.println("环绕通知---异常增强");
            throw new RuntimeException();
        }finally {
            //异常增强
            System.out.println("环绕通知---最终增强");
        }
    }
}

4、在测试类中测试注解配置的操作是否生效。

public class Test01 {
    @Test
    public void test01(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        BookService bookService = context.getBean(BookService.class);
        bookService.save(5);
    }
}

日志打印 

7.基于纯注解的AOP 

创建module项目并导入jar包

  接口

接口的实现类和增强类

配置类 

@Configuration:将想要的组件添加到容器中;

用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

@ComponentScan:表示该类是配置类

用于批量注册bean。这个注解会让spring去扫描某些包及其子包中所有的类,然后将满足一定条件的类作为bean注册到spring容器容器中。

@EnableAspectJAutoProxy:开启AOP;

@Configuration
@ComponentScan("com.zhan")//表示该类是配置类
@EnableAspectJAutoProxy
public class SpringConfig {
}

测试类 

AnnotationConfigApplicationContex:加载配置类获得IOC容器

public class Test01 {
    @Test
    public void test01(){
        //1.加载配置类获得IOC容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookService bookService = context.getBean(BookService.class);
        bookService.save(5);
    }
}

日志打印 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring中的AOP 的相关文章

随机推荐

  • dft转换与反转

    这次介绍下opencv中DFT的使用 对应的例程是 EXAMPLE dft 在图像处理领域 通过DFT可以将图像转换到频域 实现高通和低通滤波 还可以利用矩阵的卷积运算等同于其在频域的乘法运算从而优化算法降低运算量 即先将图像转换到频域 然
  • 容器化部署 Jib

    概念 Google Jib 容器化构建工具 Jib是google开源的Java容器化工具 可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库 以 Maven 和 Gradle 插件形式提供 通过 Jib Java 开发者可
  • 【省带宽、压成本专题】从产品架构来看,PCDN如何节流50%

    过去几年 我们一直在视频省流量方面潜心钻研 取得不俗的成果 本次 省带宽 压成本 系列一共会推出六篇文章 从技术迭代 硬件更新等角度出发 向大家介绍节省CDN流量 降低视频播放成本的方法 第一篇 从产品架构来看 PCDN如何节流50 目前国
  • 华为OD机试 - 欢乐的周末(Java)

    题目描述 小华和小为是很要好的朋友 他们约定周末一起吃饭 通过手机交流 他们在地图上选择了多个聚餐地点 由于自然地形等原因 部分聚餐地点不可达 求小华和小为都能到达的聚餐地点有多少个 输入描述 第一行输入m和n m代表地图的长度 n代表地图
  • 哈佛商学院私人笔记:如何一天拥有48小时?

    你的身边有没有这样一群人 永远精力充沛 永远有用不完的时间 工作 社交 生活 兴趣什么都不落下 谁都知道这得益于他们对时间的高效利用 但具体的妙招是什么呢 刚来到学校 哈佛 的时候我就被告知 你们的第一年是故意设计成很紧张的时间表 以锻炼你
  • C 标准库 - 《stdarg.h》

    原文链接 https www runoob com cprogramming c standard library stdarg h html 简介 stdarg h 头文件定义了一个变量类型 va list 和三个宏 这三个宏可用于在参数
  • STM32——DS18B20温度传感器

    一 DS18B20介绍 一 DS18B20技术性能特征 1 独特的单总线接口方式 DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯 大大提高了系统的抗干扰性 2 测温范围 55 C 125 C 3 支
  • 串口服务器485转以太网

    串口服务器485转以太网可以将485等串口设备连接到网络中 让这些设备采集的数据发往网络 建立串口和网络的透明传输通道 实现设备联网 用户可以使用组态软件或者自己编写网络通信程序和设备通信 上海卓岚串口服务器可支持虚拟串口协议 使得您也可以
  • [编程入门]自定义函数之字符串拷贝

    题目要求 有一字符串 包含n个字符 写一函数 将此字符串中从第m个字符开始的全部字符复制成为另一个字符串 include
  • java判断字符串String是否为空

    java判断字符串String是否为空 1 判空的四个方法 2 区别 和equals null和 3 推荐使用 1 判空的四个方法 1 str null length就是取得字符串的长度 2 str length 0 3 equals st
  • 亚马逊S3Client实现上传下载功能

    首先引入依赖
  • Vue3通透教程【二】更高效的构建工具—Vite

    文章目录 写在前面 webpack Vite是什么 使用Vite创建项目 写在最后 写在前面 专栏介绍 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章 应粉丝要求开始更新 Vue3 的相关技术文章 Vue 框架目前的地位大家应该都
  • 2019/10/3 CSP-S 模拟测

    T1 Permut 题意 求 1 n 的排列中逆序对数量为 k 的排列的个数 SOL 排除法我们知道一定不是 O n 的算法 考虑 dp 现在已经有 n 1 的答案了 考虑新加入一个数产生多少新的逆序对 设 dp i j 表示 1 i 的排
  • flea-cache使用之Redis集群模式接入

    Redis集群模式接入 1 参考 2 依赖 3 基础接入 3 1 定义Flea缓存接口 3 2 定义抽象Flea缓存类 3 3 定义Redis客户端接口类 3 4 定义集群模式Redis客户端实现类 3 5 定义Redis集群连接池 3 6
  • DataV:可能是我用过最可怕的数据可视化神器

    每年的双十一 天猫都会在剁手狂欢节中直播战绩 除了可怕的数字之外 不知道大家有没有留意到这些同样可怕的 数据可视化大屏 2015双十一大屏 2016双十一大屏 所谓大屏 顾名思义就是一个 很大的屏 一般应用在交易大厅 展览中心 管控中心 老
  • 关于java中IO的个人理解

    一 什么是java的I O I O中的i为input即输入的意思 O为output输出的意思 所以io为java中数据的输入和输出 这里的数据即包括网络上的数据 socket 也包括本地的文件数据 IO使用流的概念来进行数据的输入和输出也就
  • 希沃展台如何使用_【希沃视频展台--让课堂展示从未如此轻松!】PjTime.COM 综合导购 希沃...

    无论是作业试卷的讲解 还是实验过程展示 课堂展示对于课堂效率的提升始终起着重要的作用 然而目前市场上还是充斥着不少操作复杂 清晰度十分尴尬的展台产品 影响着老师的课堂效果 为此我们特意打造了希沃 7系列视频展台 一款简单又强大的视频展台 希
  • 架构师之道 秒杀系统优化思路

    本文曾在 架构师之路 上发布过 近期支援Qcon AS大会 在微信群里分享了该话题 故对原文进行重新整理与发布 一 秒杀业务为什么难做 1 im系统 例如qq或者微博 每个人都读自己的数据 好友列表 群列表 个人信息 2 微博系统 每个人读
  • Flex布局(一:基本概念和容器属性)

    前言 算上来快2个月没写博客呢 一是赶项目 二是中途接到一个朋友公司需要帮忙 周末都在TA们公司兼职 然后空下来就快12月初 1 Flex 传统的布局方案 基于css盒子模型 float display position TA对于很多特殊布
  • Spring中的AOP

    1 概述 在软件业 AOP为Aspect Oriented Programming的缩写 意为 面向切面编程 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 AOP是OOP的延续 是软件开发中的一个热点 也是Spring框