一起学SF框架系列7.2-spring-AOP-AOP使用

news2024/11/24 22:50:56

Spring AOP有两种使用模式:@AspectJ配置模式和xml配置模式。

@AspectJ配置模式

配置

1、加入依赖包:

    <!--spring aop依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>6.0.2</version>
    </dependency>
    <!-- spring aspects依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>6.0.2</version>
    </dependency>

2、配置文件加入:

<beans xmlns="http://www.springframework.org/schema/beans"
	...
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		...
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 开启aop注解方式,默认为false -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

示例

切面定义

@Component
// @Aspect切面注解,表示该类是切面类
@Aspect
public class AspectLog { 
	// before advice,括号中是切入点配置,省略了“pointcut”(execution是pointcut语法的固定开头) 注1
    @Before("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void before() {
		System.out.println("方法执行advice-before");
	}

	// After advice,括号中是切入点配置,省略了“pointcut”
    @After("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void after() {
		System.out.println("方法执行advice-after");
	}

	// AfterReturning advice,括号中是切入点配置,省略了“pointcut”
    @AfterReturning("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void afterReturning() {
		System.out.println("方法执行advice-afterReturning");
	}

	// Around advice,括号中是切入点配置,省略了“pointcut” 注2
    /**在使用环绕注解时,可以传入ProceedingJoinPoint的对象来获取业务方法的返回值*/
    @Around("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.around*(..))")
    public void around(ProceedingJoinPoint pj) throws Throwable {
        // 执行方法前处理
        System.out.println("方法执行advice-@Around前");
        // 执行方法本身
        BzService bzService =(BzService) pj.proceed();
        // 执行方法后处理
        System.out.println("方法执行advice-@Around后,返回值-"+bzService);
    }

	// AfterThrowing advice,其中pointcut是切入点,throwing是传入切面异常命名为"ex" 注3
    @AfterThrowing(pointcut="execution(* com.learnsf.demo.spring.aop.BzServiceImpl.throw*(..))",throwing="ex")
	public void afterThrowing(JoinPoint jp, Throwable ex) {
		System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception: "+ex.getMessage());
	}
}

注1:如何定义切入点见后续章节。
注2: ProceedingJoinPoint 继承于 JoinPoint 。其中“pj.proceed()”是执行连接点方法本身。这是around advice的特点:需要切面程序自己执行连接点方法本身;其它advice是框架来执行的。
注3:JoinPoint接口是提供切面可以访问连接点方法的信息,有用的方法如下:
getArgs():返回方法参数。
getThis():返回代理对象。
getTarget():返回目标对象。
getSignature():返回当前Advice的方法描述。
toString():打印所当前Advice方法的描述。

例子类

public interface BzService {
    public void add();

    public void delete();

    public void update();

    public void query();
    
    public BzService aroundTest();
    
	public BzServiceImpl throwTest() throws Exception;
}

@Component
public class BzServiceImpl implements BzService{
	@Override
    public void add() {
        System.out.println("业务增加!");
    }

	@Override
    public void delete() {
        System.out.println("业务删除!");
    }

	@Override
    public void update() {
        System.out.println("业务修改!");
    }

	@Override
    public void query() {
        System.out.println("业务查询!");
    }

	@Override
	public BzServiceImpl aroundTest() {
        System.out.println("该方法被@Around Annotation!");
        return null;
    }
	@Override
	public BzServiceImpl throwTest() throws Exception{
        System.out.println("该方法被throw!");
		throw new IllegalArgumentException("测试异常抛出");
	}
}

运行类

@Component
public class DemoAop {
	@Autowired
	BzService bzService;
	
	public void demo() {
		bzService.add();
		bzService.delete();
		bzService.update();
		bzService.aroundTest();
		try {
			bzService.throwTest();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
}

// 主程序
public class Main {
    public static void main(String[] args) {
        //创建springframework容器,初始化文件为app.xml
    	ApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
        DemoAop demoAop = (RunDemo)context.getBean("DemoAop");
        demoAop .demo();
    }
}

XML配置模式

配置

配置文件加入:

<beans xmlns="http://www.springframework.org/schema/beans"
	...
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		...
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

	...
	<!--AOP实现方式之一:xml配置模式-->
    <aop:config>
        <!-- 定义切入点:id切入点的id,expression:确定要切入的地方和其详细信息  -->
        <aop:pointcut id="pointcut" expression="execution(* com.learnsf.demo.spring.aop.BzServiceImplForXml.*(..))"/>
        <!-- 同切面关联:advice-ref定义切面 使用的切点pointcut-ref -->
        <aop:advisor advice-ref="springAopLog" pointcut-ref="pointcut"/>
    </aop:config>
    ...

示例

切面类

// 通过继承实现对方法的参数、返回值等的访问
@Component
public class SpringAopLog implements MethodBeforeAdvice,AfterReturningAdvice {
	// implement MethodBeforeAdvice(BeforeAdvice只是个标记接口,MethodBeforeAdvice为实际接口)
	@Override
	public void before(Method method, Object[] args, @Nullable Object target) {
		System.out.println("[前置Advice]: "+target.getClass().getName()+"的"+method.getName()+"方法被执行了");
	}

	//implement AfterReturningAdvice(AfterAdvice只是个标记接口,AfterReturningAdvice为实际接口)
	// returnValue:切入目标方法的返回值,切入的后置方法可以对返回值进行操作
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("[后置Advice]: 执行了"+method.getName()+"方法,返回值为"+returnValue);
    }
}

例子类

@Component
public class BzServiceImplForXml {
    public BzPojo add(BzPojo bzPojo) {
        System.out.println("BzServiceImplForXml-业务增加!");
        return bzPojo;
    }

    public BzPojo update(BzPojo bzPojo) {
        System.out.println("BzServiceImplForXml-业务修改!");
        return bzPojo;
    }

    public boolean delete(Integer id) {
        System.out.println("BzServiceImplForXml-业务删除!");
        return true;
    }

    public void query(Integer id) {
        System.out.println("BzServiceImplForXml-业务查询!");
    }
}

运行

@Component
public class DemoAop {
	@Autowired
	BzServiceImplForXml bzServiceImplForXml;
	
	public void demo() {
		BzPojo bzPojo=new BzPojo();
		bzServiceImplForXml.add(bzPojo);
		bzServiceImplForXml.update(bzPojo);
		bzServiceImplForXml.delete(1);
	}
}
// 主程序
public class Main {
    public static void main(String[] args) {
        //创建springframework容器,初始化文件为app.xml
    	ApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
        DemoAop demoAop = (RunDemo)context.getBean("DemoAop");
        demoAop .demo();
    }
}

应用如何选择

应用如何选择@AspectJ配置模式或XML配置模式,需了解两者区别:
1、用Spring AOP同时支持@AspectJ配置模式或XML配置模式。如果只用完整的AspectJ,则只能用@AspectJ模式。
2、XML配置模式是Spring一诞生就用的模式,也是很多程序员最熟悉的模式。因此,当使用AOP作为配置企业服务的工具时,XML可能是一个不错的选择。xml配置模式优点是:1、从配置中更清楚地看到系统中存在哪些方面;2、可独立于程序更改配置。同时也存在两个缺点:首先,它没有在单个位置完全封装它所解决的需求的实现,违反DRY原则(即系统中的任何职责都应该有一个单一的、明确的表示);其次,与@AspectJ配置模式相比,XML配置模式在其可以表达的内容方面稍有限制:仅支持“singleton”方面实例化模型,并且不可能组合在XML中声明的命名切入点。
实际上,两者可以混用。

Pointcut表达式语法

Pointcut(切入点)的语法(引用自:https://blog.51cto.com/panyujie/5604327)。
在这里插入图片描述

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

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

相关文章

Gartner发布2023年的存储技术成熟曲线

技术路线说明 Gartner自1995年起开始采用技术成熟度曲线&#xff0c;它描述创新的典型发展过程&#xff0c;即从过热期发展到幻灭低谷期&#xff0c;再到人们最终理解创新在市场或领域内的意义和角色。 一项技术 (或相关创新)在发展到最终成熟期的过程中经历多个阶段&#xff1…

接口也默认继承Object类

目标&#xff1a; 1. 知道接口也默认继承Object类 2. 感受继承和重写在向上转型中的作用有多大 引出问题&#xff1a; 在我用 List接口的引用list 接收ArrayList这个集合类的实例时&#xff08;此处发生向上转型&#xff09;&#xff0c;偶然发现&#xff0c;咦&#xff0c…

【Python常用函数】一文让你彻底掌握Python中的toad.selection.select函数

任何事情都是由量变到质变的过程&#xff0c;学习Python也不例外。只有把一个语言中的常用函数了如指掌了&#xff0c;才能在处理问题的过程中得心应手&#xff0c;快速地找到最优方案。本文和你一起来探索Python中的toad.selection.select函数&#xff0c;让你以最短的时间明白…

Grounding dino + segment anything + stable diffusion 实现图片编辑

目录 总体介绍总体流程 模块介绍目标检测&#xff1a; grounding dino目标分割&#xff1a;Segment Anything Model (SAM)整体思路模型结构&#xff1a;数据引擎 图片绘制 集成样例 其他问题附录 总体介绍 总体流程 本方案用到了三个步骤&#xff0c;按顺序依次为&#xff1a…

YOLOv5入门实践(2)— 手把手教你使用make sense标注数据集(附工具地址+使用教程)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。鉴于labelimg图像标注软件安装起来比较麻烦&#xff0c;本节课再给大家介绍另外一款数据集标注工具。这是一款在线标注数据集的工具&#xff0c;用起来非常的方便。&#x1f308; 前期回顾&#xff1a; YOLOv5入门实践&…

当执行MOV [0001H] 01H指令时,CPU都做了什么?

今天和几位单位大佬聊天时&#xff0c;讨论到一个非常有趣的问题-当程序执行MOV [0001H], 01H计算机实际上都做了哪些工作&#xff1f;乍一看这个问题平平无奇&#xff0c;CPU只是把立即数01H放在了地址为0001的内存里&#xff0c;但仔细想想这个问题远没有那么简单&#xff0c…

SystemVerilog之覆盖率详解

文章目录 1.0 覆盖率前言1.1 覆盖率类型1.2 覆盖策略及覆盖组1.3 覆盖率数据采样1.3.1 bin的创建与使用1.3.2 条件覆盖率1.3.3 翻转覆盖率1.3.4 wildcard覆盖率1.3.5 忽略bin与非法bin 1.4 交叉覆盖率1.4.1 排除部分cross bin1.4.2 精细化交叉覆盖率1.4.3 单个实例的覆盖率1.4.…

定量分析计算51单片机复位电路工作原理 怎么计算单片机复位电容和电阻大小

下面画出等效电路图 可以知道单片机内必然有一个电阻RX&#xff0c;为了简化分析&#xff0c;我们假设他是线性电阻&#xff08;不带电容&#xff0c;电感的支路&#xff09; 还有一个基础知识&#xff1a; 电容器的充电放电曲线&#xff1a; 还需要知道电容电压的变化是连续…

【简单认识zookeeper+kafka分布式消息队列集群的部署】

文章目录 一、zookeeper1、定义2、工作机制3、Zookeeper 特点4、Zookeeper 数据结构5、Zookeeper 应用场景6、Zookeeper 选举机制&#xff08;1&#xff09;第一次启动选举机制&#xff08;2&#xff09;非第一次启动选举机制 7、部署zookeeper群集 二、消息队列概述1、为什么需…

《线性调频雷达典型有源干扰抑制技术研究》阅读记录

文章目录 《线性调频雷达典型有源干扰抑制技术研究》 阅读记录&#xff08;1&#xff09;研究背景与意义&#xff1a;&#xff08;2&#xff09;有源压制干扰&#xff08;3&#xff09;有源欺骗式干扰&#xff08;4&#xff09;压制干扰的抑制&#xff08;5&#xff09;欺骗干扰…

面试热题(全排列)

给定一个不含重复数字的整数数组 nums &#xff0c;返回其 所有可能的全排列 。可以 按任意顺序 返回答案。 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 先在这里说明一下排列和组合的区别? 组合&#xff1a;是指从一…

[gdc]Rendering ‘God of War Ragnark‘

gdc23&#xff0c; sony santa monica关于god of war的分享&#xff1b; back ground 作者stephen mcauley现在是santa monica的technical director&#xff1b;20年加入santa monica&#xff0c;作为rendering lead&#xff0c;有9年的经验&#xff0c;之前在ubisoft montre…

[鹤城杯 2021]Middle magic 解题思路过程

过程 打开题目&#xff0c;是一道PHP的代码审计。代码如下&#xff1a; <?php highlight_file(__FILE__); include "./flag.php"; include "./result.php"; if(isset($_GET[aaa]) && strlen($_GET[aaa]) < 20){$aaa preg_replace(/^(.*)…

河道水位自动监测预警 yolov5

河道水位自动监测预警系统基于yolov5网络模型AI视频智能水尺读数技术&#xff0c;河道水位自动监测预警系统通过在河道周边布设监控摄像头&#xff0c;实时监测水位的变化&#xff0c;一旦水位超过预设阈值&#xff0c;将自动发出预警信号&#xff0c;并提示相关人员采取相应的…

计算机网络-物理层(一)物理层的概念与传输媒体

计算机网络-物理层&#xff08;一&#xff09;物理层的概念与传输媒体 物理层相关概念 物理层的作用用来解决在各种传输媒体上传输比特0和1的问题&#xff0c;进而为数据链路层提供透明(看不见)传输比特流的服务物理层为数据链路层屏蔽了各种传输媒体的差异&#xff0c;使数据…

Java 基础知识点

Object 类相关方法 getClass 获取当前运行时对象的 Class 对象。 hashCode 返回对象的 hash 码。 clone 拷贝当前对象&#xff0c; 必须实现 Cloneable 接口。浅拷贝对基本类型进行值拷贝&#xff0c;对引用类型拷贝引用&#xff1b;深拷贝对基本类型进行值拷贝&#xff0c;对…

CentOS7.7.1908升级python3版本

介绍 本文将详细介绍在CentOS7.7.1908系统的服务器将自带的python版本升级到3.8.0版本的过程。 在升级前CentOS7.7.1908中已经存在旧python版本。 查看CentOS版本命令&#xff1a; cat /etc/centos-release升级前后的python版本&#xff08;python3升级前为3.6.8&#xff09…

开箱报告,Simulink Toolbox库模块使用指南(三)——Simscape 电路仿真模块

文章目录 前言 Simscape 电路仿真模块 模型搭建 仿真求解 分析和应用 总结 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;一&#xff09;——powergui模块》 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;二&#xf…

grafana中利用变量来添加dashboard详情页地址实现点击跳转

背景 最近弄grafana的dashboard,突然想到各个dashboard之前可以直接跳转到不同详细页面的面板,于是找了找实现方法 实现 以stat 格式的面板为例,显示出各个pod的对应状态, PromQL是(avg(kube_pod_status_phase{phase"Running", namespace!"kube-system"…

用友U8+CRM 任意文件上传+读取漏洞复现(HW0day)

0x01 产品简介 用友U8 CRM客户关系管理系统是一款专业的企业级CRM软件&#xff0c;旨在帮助企业高效管理客户关系、提升销售业绩和提供优质的客户服务。 0x02 漏洞概述 用友 U8 CRM客户关系管理系统 getemaildata.php 文件存在任意文件上传和任意文件读取漏洞&#xff0c;攻击…