spring核心技术(下)--面向切面aop的特点加案例论证

news2024/9/26 1:24:31

目录

一.spring的aop的特点

        1.1 aop的简介

        1.2 举例

二.spring的aop的专业术语

三.论证模拟

        3.1.前置通知

        3.2.后置通知

        3.3.环绕通知

         3.4.异常通知

        3.5.过滤通知

今天就分享到这啦!!


一.spring的aop的特点

        Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架 。 上一篇已经讲解了IoC控制反转的特点,今天我们来了解面向切面AOP的世界吧!!


        1.1 aop的简介

                Spring的AOP(面向切面编程)可以理解为在编程中,我们常常会有一些通用的功能需求,比如记录日志、事务管理、权限验证等一些非业务核心代码。这些功能可能会散落在很多代码中,如果每次都手动去添加这些功能,不仅麻烦还容易出错。而AOP就是为了解决这个问题而产生的。

       1. AOP的第一个特点是它能够将这些通用功能从业务逻辑中分离出来,形成一个独立的模块,我们把这个模块称为切面(Aspect)。切面里面包含了要执行的通用功能代码。

        2. 松耦合:AOP通过在运行时动态地将切面织入到目标对象中,实现了对目标对象的横向切面扩展。这种方式不需要修改目标对象的代码,只需要在配置文件中指定切点和切面的关系,从而实现了目标对象和切面之间的松耦合。

        3. 代码复用:AOP将通用功能封装在切面中,可以在多个目标对象中复用同一个切面,避免了代码的重复编写,提高了代码的复用性。

        4. 面向切面的编程:AOP允许我们通过切面来对多个目标对象的多个方法进行统一的管理。我们可以在切面中定义通用的功能,并通过切点来指定目标对象的哪些方法需要应用这个通用功能。

        总的来说,AOP的特点包括将通用功能从业务逻辑中分离出来、松耦合、代码复用和面向切面的编程。这些特点使得AOP成为了一个重要的编程范式,可以提高代码的可维护性、可扩展性和开发效率。

        1.2 举例

                比如:当我们大家伙合伙做一个线上书城的项目,如果其中有个贪心的人使用系统,上架了一本明令禁止售卖的书,然后被人举报了,但是这个时候贪心的人下架了该书,而那个人又没有截图,证据,那是不是就发现不了,再者如果客户已经在该系统中下单,但是,客户付了钱之后,那个贪心的人想白嫖将该订单删除,那是不是就没有记录,客户也找不到投诉,那么这个时候,我们就要在系统添加日志文件,记录每一次的交易,上架,下架的数据,那么是不是就可以被记录,而spring的aop就是这样的来完成这些,除必要的增删改之外的技术代码,非业务的核心代码

二.spring的aop的专业术语

        之前我们的项目代码但是从上往下依次执行,而现在加入了面向切面的思想,所以当我们的代码执行到目标对象是,查看连接点是否有前置通知,先执行前置通知,再执行目标方法,如果没有前置通知,那么就直接执行目标方法,最后看连接点上是否有后置通知,如果有,就再执行后置通知,如果没有就执行完了

  1.  连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.
  2.  目标(Target):被通知(被代理)的对象,就是完成具体的业务逻辑 ,比如书籍的增删改查
  3. 通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)  ,完成切面编程,非业务核心代码
  4.  代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),  例子:外科医生+护士只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的
  5. 切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点 , (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序),比如给新增方法添加日志功能
  6.   适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

         注:目标对象只负责业务逻辑代码

        通知对象负责AOP代码,这二个对象都没有AOP的功能,只有代理对象才有

三.论证模拟

        3.1.前置通知

        首先,我们先写service接口和实现类进行模拟,在里面写两个方法

package com.zking.aop.service;

/**
 * @author yinzi
 * @create 2023-08-17 14:52
 */
public interface IBookService {
    // 购书
    public boolean buy(String userName, String bookName, Double price);

    // 发表书评
    public void comment(String userName, String comments);
}

        然后,写实现类,重新这两个方法,并且做了一个价格的判断

package com.zking.aop.service;

import com.zking.exception.PriceException;

/**
 * @author yinzi
 * @create 2023-08-17 14:54
 */
public class BookServiceImpl implements IBookService{


    public BookServiceImpl() {
        super();
    }

    public boolean buy(String userName, String bookName, Double price) {
        // 通过控制台的输出方式模拟购书
        if (null == price || price <= 0) {
            throw new PriceException("book price exception");
        }
        System.out.println(userName + " 买了 " + bookName + ", 花了 " + price);
        return true;
    }

    public void comment(String userName, String comments) {
        // 通过控制台的输出方式模拟发表书评
        System.out.println(userName + "评论:" + comments);
    }
}

        接下来要写上面价格判断的异常 

package com.zking.exception;

public class PriceException extends RuntimeException {

	public PriceException() {
		super();
	}

	public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public PriceException(String message, Throwable cause) {
		super(message, cause);
	}

	public PriceException(String message) {
		super(message);
	}

	public PriceException(Throwable cause) {
		super(cause);
	}
	
}

        然后,我们先创建一个类,将类名.方法名,携带的参数,作为日志存储到数据库。

package com.zking.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 调用项目中的某一接口实现类的方式时,将类名.方法名,携带的参数,作为日志存储到数据库。
 * @author yinzi
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

    public void before(Method method, Object[] args, Object target) throws Throwable {
        String targetName = target.getClass().getName();//方法类
        String methodName = method.getName();//方法的名字
        String params = Arrays.toString(args);//方法参数
        String msg = "【系统日志】:前置日志->"+targetName+"."+methodName+",携带的参数:"+params;
        System.out.println(msg);

    }

}

        最后,我们进行一个配置

 前台论证:

        3.2.后置通知

        有了前面的铺垫,现在我们直接再创建一个后置通知的类,比起前置通知,多了一个参数,就是返回参数

package com.zking.aop.advice;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author yinzi
 * @create 2023-08-17 15:51
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        String targetName = target.getClass().getName();
        String methodName = method.getName();
        String params = Arrays.toString(args);
        String msg = "【系统日志】:后置日志->" + targetName + "." + methodName + ",携带的参数:" + params + ";目标对象所调用的方法的返回值:"
                + returnValue;
        System.out.println(msg);
    }


}

        其次,配置文件即可

 最后,前台看结果:

        3.3.环绕通知

        就是结合了前置通知和后置通知,它两个都有所以一般常用这个,

        它只有一个参数,但是这一个参数相当于上面前置通知和后置通知的3,4个参数

package com.zking.aop.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 环绕通知
 * @author Administrator
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object target = invocation.getThis();
        Method method = invocation.getMethod();
        Object[] args = invocation.getArguments();
        String targetName = target.getClass().getName();
        String methodName = method.getName();
        String params = Arrays.toString(args);
        String msg = "【环绕通知】:正在调用->" + targetName + "." + methodName + ",携带的参数:" + params;
        System.out.println(msg);
        Object returnValue = invocation.proceed();
        String msg2 = "【环绕通知】:目标对象所调用的方法的返回值:" + returnValue;
        System.out.println(msg2);
        return returnValue;
    }


}

             然后就是配置文件

 最后前台测试:

    3.4.异常通知

        老样子,先建一个类,但是注意,这个异常通知的类,重写的话,方法名字只能是这个,否则报错

 然后就是配置文件

 最后前台测试;

因为前面那个异常的类,及service类做了价格的判断

        3.5.过滤通知

        过滤通知就是那个适配器,它不需要再建一个类,直接再配置文件里面配置就可以了,需要正则判断,这里举例过滤的是后置通知

 前台结果:

今天就分享到这啦!!

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

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

相关文章

go es实例

go es实例 1、下载第三方库 go get github.com/olivere/elastic下载过程中出现如下报错&#xff1a; 解决方案&#xff1a; 2、示例 import package mainimport ("context""encoding/json""fmt""reflect""time""…

电脑文件删除了可以找回吗?3种文件恢复办法!

在日常工作中&#xff0c;我们经常会需要处理很多的工作文件&#xff0c;但有时候会不小心误删电脑中的文件。 那么&#xff0c;电脑上面的文件被删除了可以找回吗&#xff1f;答案是肯定的&#xff01;下面就来分享三种比较好用的方法&#xff0c;一起来看下吧。 方法一&…

C++初阶——构造函数的初始化列表

前言&#xff1a;C中&#xff0c;初始化列表是构造函数中极为重要的一部分,是每个成员变量定义的地方。 目录 一.什么是初始化列表二.何时用初始化列表声明处赋值——缺省值 三.注意点 一.什么是初始化列表 初始化列表是每个成员变量定义的地方。不管我们有没有写&#xff0c;成…

带你了解—使用内网穿透,公网远程访问本地硬盘文件

文章目录 前言1. 下载cpolar和Everything软件3. 设定http服务器端口4. 进入cpolar的设置5. 生成公网连到本地内网穿透数据隧道 总结 前言 随着云概念的流行&#xff0c;不少企业采用云存储技术来保存办公文件&#xff0c;同时&#xff0c;很多个人用户也感受到云存储带来的便利…

测试右移,也就是生产环境下的QA

一、一个生产环境 Bug 的解决办法 先来跟大家分享一个生产环境下的 Bug&#xff1a; 一个在线订购葡萄酒的系统&#xff0c;订购流程相对复杂&#xff0c;下单过程中后台会有随机的失败&#xff0c;系统采取的措施是重试&#xff0c;就是说顾客下单后&#xff0c;后台如果有错…

中期国际:MT4数据挖掘与分析方法:以数据为导向,制定有效的交易策略

在金融市场中&#xff0c;制定有效的交易策略是成功交易的关键。而要制定一份可靠的交易策略&#xff0c;数据挖掘与分析方法是不可或缺的工具。本文将介绍如何以数据为导向&#xff0c;利用MT4进行数据挖掘与分析&#xff0c;从而制定有效的交易策略。 首先&#xff0c;我们需…

易服客工作室:Uncode主题 - 创意和WooCommerce WordPress主题

Uncode主题是一款像素完美的创意 WordPress 主题&#xff0c;适用于任何类型的网站&#xff08;作品集、代理机构、自由职业者、博客&#xff09;&#xff0c;也是适用于商店&#xff08;电子商务、在线商店、企业&#xff09;的顶级 WooCommerce 主题。Uncode 的设计非常注重细…

C linux struct sigaction

在linux中定义struct sigaction结构体时, 在已经包含signal.h头文件的情况下, 仍旧提示找不到这个结构体. 需要在代码中定义 _POSIX_C_SOURCE 宏&#xff0c;并将其设为大于等于 199309L 的值。这样可以确保相关的函数和结构体在编译时可用。 这将告诉编译器以符合 POSIX 标准要…

vue项目打包成exe

目标&#xff1a;vue的项目打包成为exe可执行文件 工具&#xff1a;需要使用到Electron框架 首先&#xff0c;我们了解一下什么是Electron&#xff1b; Electron 是由 GitHub 开发而成的。它是使用 JavaScript&#xff0c;HTML 和 CSS 构建跨平台的桌面应用程序的框架&#…

[JavaWeb]【三】Maven

目录 一 什么是Maven 二 Maven的作用 2.1 依赖管理 2.2 统一项目目录 2.3 标准项目构建 三 Maven概述 3.1 介绍 3.2 安装 四 IDEA集成Maven 4.1 配置Maven环境 4.1.1 单个项目配置 4.1.1.1 创建项目 4.1.1.2 配置项目JDK版本 4.1.1.3 配置maven 4.1.2 配置全局Maven环…

2023年我国重点水利工程建设全面提速,数字孪生赋能智慧水利

一、水利工程行业概述和分类 从定义上来看&#xff0c;水利工程是用于控制和调配自然界的地表水和地下水&#xff0c;达到除害兴利目的而修建的工程。也称为水工程。 根据观研报告网发布的《中国水利工程行业现状深度调研与投资趋势预测报告&#xff08;2023-2030年&#xff…

入门jdk1.8处理空指针API-Optional

文章目录 入门jdk1.8处理空指针API-Optional类图结构简要说明常用api实践操作应用场景场景一&#xff1a; 对象不为空&#xff0c;做一些逻辑处理场景二&#xff1a;对象为空抛异常&#xff0c;或者对象某个字段为空抛指定异常场景三&#xff1a;级联判空&#xff0c;父节点&am…

【Control Net】第二章——模型介绍,线稿类

ControlNet1.1版本中发布了15个模型,有点过于多了。这里给分成三类: 线稿类(5个) 线稿类顾名思义,是处理线稿的,或者把图片提取成线稿的。 Canny,硬边缘提取 最早的边缘提取算法,提取的效果已经不如Lineart效果好了,处理有些粗糙。 MLSD,直线检测 可以识别建筑、…

【Linux】查看系统内存命令(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【Apollo】赋能移动性:阿波罗自动驾驶系统的影响

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…

Nvidia Jetson 编解码开发(1)介绍

前言 由于项目需要,需要开发Jetson平台的硬件编解码; 优化CPU带宽,后续主要以介绍硬件编解码为主 1.Jetson各平台编解码性能说明 如下是拿了Jetson nano/tx2/Xavier等几个平台做对比; 这里说明的编解码性能主要是对硬件来说的 2. 编解码实现说明 2.1 软件编解码 优点:…

CAS 一些隐藏的知识,您了解吗

目录 ConcurrentHashMap 一定是线程安全的吗 ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 内部使用的是数组加链表加红黑树的结构&#xff0c;通过CASvolatile或synchronized的方式来保证线程安全的,这些原理已毋庸置疑&#xff0c;一言不合上代码. 模拟2个线程累计&#…

I/O软件层次到底是怎么分的?以及对库函数和系统调用的一些联想

其中&#xff0c;设备驱动程序和中断处理程序是直接和硬件打交道的 相关题目&#xff1a; 将系统调用参数翻译成设备操作命令的工作由&#xff08;&#xff09;完成 A. 用户层I/O&#xff1b; B. 设备无关的操作系统软件&#xff1b;C. 中断处理&#xff1b;D. 设备驱动程序 …

vue3 videojs实现播放器,动态更改src

一、背景 vue3下载第三方插件videojs&#xff0c;达到播放器的效果&#xff0c;并且点击事件能够动态更改播放器的src。实现思路&#xff1a; 场景一&#xff1a;只有一个播放器&#xff0c;当点击事件&#xff0c;直接赋值&#xff0c;动态更改封装好的组件的src参数&#xff…

【AI】如何用AI生成XMind思维导图

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff0c;物联网搬砖工一名&#xff0c;致力于为大家淘出更多好用的AI工具&#xff01; 背景 随着人工智能技术的不断发展&#xff0c;越来越多的应用场景开始涉及到AI技术。在办公软件领域&#xff0c;XMind是一款非常受欢迎…