Spring-aop特点,专业术语及案例演示

news2024/9/21 23:41:21

一.aop简介

AOP(Aspect-Oriented Programming)是Spring框架的一个重要特性,它通过将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来,以模块化的方式在整个应用程序中重复使用。以下是关于AOP的简介及其特点:

简介:

  • AOP是一种编程范式,它通过将横切关注点切割出来,将其模块化,并将其应用于多个类和模块,以提高代码的重用性和可维护性。
  • 横切关注点是指与核心业务逻辑无关但存在于多个类或模块中的非功能性需求,例如日志记录、性能监控、事务管理等。

特点:

  1. 模块化:AOP允许将横切关注点从核心业务逻辑中提取出来,形成独立的切面(Aspect),使得关注点的逻辑可以独立于各个模块。
  2. 解耦:AOP通过解耦横切关注点与核心业务逻辑,使得它们可以独立演化和变化,提高了模块之间的松耦合程度。
  3. 重用性:AOP允许将切面应用于多个类和模块,从而实现了关注点的重用,避免了代码的重复编写。
  4. 可维护性:将横切关注点抽象为切面后,使得代码结构更清晰,易于理解和维护。
  5. 动态性:AOP可以在运行时动态地将切面应用到目标对象上,而不需要修改目标对象的源代码,增强了系统的灵活性和可扩展性。
  6. 多样性:Spring框架支持不同类型的切面编程,包括基于代理的AOP和基于字节码增强的AOP。这样可以选择最适合应用程序需求的AOP实现方式。

在Spring框架中,AOP的实现采用了代理模式和动态代理技术。Spring提供了多种AOP的实现方式,包括基于XML配置的AOP、基于注解的AOP和基于纯Java配置的AOP(JavaConfig)等,开发者可以根据具体需求选择适合的方式来配置和使用AOP。

 二.aop中的专业术语

  1. 切面(Aspect):切面是一个模块化单元,用于解耦和封装横切关注点的逻辑。切面由切点和通知组成,它定义了何时在何处应用通知。

  2. 切点(Pointcut):切点定义了在应用程序中哪些位置应该应用通知。它通过表达式或模式匹配规则来指定需要被拦截的连接点(Join Point)。

  3. 连接点(Join Point):连接点是在应用程序执行过程中可以插入切面的特定点。例如方法执行、异常抛出、字段访问等都可以是连接点。

  4. 通知(Advice):通知是在切面的特定连接点上执行的动作。在Spring AOP中,有以下几种通知类型:

    • 前置通知(Before Advice):在连接点之前执行的通知。
    • 后置通知(After Advice):在连接点之后执行的通知。
    • 返回通知(After Returning Advice):在连接点成功完成后执行的通知。
    • 异常通知(After Throwing Advice):在连接点发生异常时执行的通知。
    • 环绕通知(Around Advice):在连接点前后都执行的通知,可以控制方法的执行。
  5. 引入(Introduction):引入是一种给现有类添加新方法或属性的方式。它允许在不修改原始类代码的情况下,向类添加新功能。

  6. 织入(Weaving):织入是将切面应用到目标对象上以创建新的代理对象的过程。在Spring AOP中,织入可以在编译时、类加载时或运行时进行。

  7. 目标对象(Target Object):目标对象是被切面通知的真实对象。它是应用程序中具体业务逻辑的实现。

  8. 异常处理(Exception Handling):异常处理是在连接点发生异常时,切面执行的特定动作。它可以捕获和处理异常,提供错误处理或回滚事务等功能。

三.案例演示 

1.前置通知

1.1 先准备接口

package com.YU.aop.biz;

public interface IBookBiz {
	// 购书
	public boolean buy(String userName, String bookName, Double price);

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

1.2然后再准备好实现类

package com.YU.aop.biz.impl;

import com.YU.aop.biz.IBookBiz;
import com.YU.aop.exception.PriceException;

public class BookBizImpl implements IBookBiz {

	public BookBizImpl() {
		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 + " buy " + bookName + ", spend " + price);
		return true;
	}

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

}

1.3对我们的目标对象进行JavaBean配置 

<!--目标对象-->
    <bean class="com.YU.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

1.4 编写前置系统日志通知

package com.YU.aop.advice;

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

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 买书、评论前加系统日志
 * @author YU
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//		在这里,可以获取到目标类的全路径及方法及方法参数,然后就可以将他们写到日志表里去
		String target = arg2.getClass().getName();
		String methodName = arg0.getName();
		String args = Arrays.toString(arg1);
		System.out.println("【前置通知:系统日志】:"+target+"."+methodName+"("+args+")被调用了");
	}

}

1.5配置系统通知XML中的JavaBean

<!--通知-->
    <bean class="com.YU.aop.advice.MyMethodBeforeAdvice" id="myMethodBeforeAdvice"></bean>

1.6 配置代理XML中的JavaBean

<!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象 -->
        <property name="target" ref="bookBiz"></property>
        <!-- 配置代理接口,目标对象的接口 -->
        <property name="proxyInterfaces">
            <value>com.YU.aop.biz.IBookBiz</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>myMethodBeforeAdvice</value>
            </list>
        </property>
    </bean>

1.7 测试代码开始测试

package com.YU.aop.test;

import com.YU.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author YU
 * @create 2023-08-17 15:14
 */
public class Test1 {
    public static void main(String[] args) {
        //建模
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//        IBookBiz bookBiz = (IBookBiz) context.getBean("bookBiz");
        IBookBiz bookBiz = (IBookBiz) context.getBean("bookProxy");
        bookBiz.buy("死仔","我的26岁女房客",18.8d);
        bookBiz.comment("死仔","真好看");
    }
}

测试结果:

 由测试结果可得知,不仅获取到了我们的参数,同时根据方法获取到了我们的系统日志,也就是前置通知

2. 后置通知

2.1 先准备好后置通知的系统日志

package com.zking.aop.advice;
	
import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

/**
 * 买书返利
 * @author Administrator
 *
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
		String target = arg3.getClass().getName();
		String methodName = arg1.getName();
		String args = Arrays.toString(arg2);
		System.out.println("【后置通知:买书返利】:"+target+"."+methodName+"("+args+")被调用了,"+"该方法被调用后的返回值为:"+arg0);
	

	}

}

2.2 配置后置系统通知的XML的JavaBean

<!--后置通知-->
    <bean class="com.YU.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>

并在前面已经配置好的代理接口中添加一个value值

 2.3 测试结果

 由测试结果我们可以得知,后置通知永远都在方法执行后才会显示通知,与前置通知不同的是每次前面的方法调用后都会返回一个参数

3.环绕通知

3.1 环绕通知就是前置通知和后置通知的结合,在实际应用开发中,我们一般不会单独编写前置通知和后置通知,单独使用前置通知或者后置通知时,我们会使用环绕通知,将里面前置(后置)通知的功能注释,以达到单独使用的目的

3.2 环绕通知的系统日志

package com.YU.aop.advice;

import java.util.Arrays;

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

/**
 * 环绕通知
 * 	包含了前置和后置通知
 * 
 * @author Administrator
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		String target = arg0.getThis().getClass().getName();
		String methodName = arg0.getMethod().getName();
		String args = Arrays.toString(arg0.getArguments());
		System.out.println("【环绕通知调用前:】:"+target+"."+methodName+"("+args+")被调用了");
//		arg0.proceed()就是目标对象的方法
		Object proceed = arg0.proceed();
		System.out.println("【环绕通知调用后:】:该方法被调用后的返回值为:"+proceed);
		return proceed;
	}

}

3.3 配置环绕通知的XML的JavaBean与前置通知和后置通知一致

3.4 测试结果

 

由测试结果得知,环绕通知就是前置通知和后置通知的结合,优点就是不需要再多次去进行配置及编码,所以就像我们前面所说在实际开发应用中我们一般都会选择使用环绕通知

4.异常通知

4.1 异常通知的系统日志和其他系统日志不同的是,方法名为固定的afterThrowing,不能修改

package com.YU.aop.advice;

import org.springframework.aop.ThrowsAdvice;

import com.YU.aop.exception.PriceException;

/**
 * 出现异常执行系统提示,然后进行处理。价格异常为例
 * @author Administrator
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(PriceException ex) {
		System.out.println("【异常通知】:当价格发生异常,那么执行此处代码块!!!");
	}
}

4.2 在我们正常程序出问题没有去配置异常通知时会出现报错,并且不会执行后面的后置通知,如以下情况

4.3 异常处理配置和前面的配置相同

4.4 当我们配置好异常通知模块时,程序出现异常时会上报日志进行提示

5.过滤通知

5.1 直接在XML中配置JavaBean

<!--过滤通知-->
    <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="regexpMethodPointcutAdvisor">
        <property name="advice" ref="myAfterReturningAdvice"></property>
        <property name="pattern" value=".*buy"></property>
    </bean>

 

将图中指出部分替换成过滤通知

 测试结果:

对比框中内容,在调用过buy方法后进行过滤,第二次调用时不再buy方法而是comment方法 

四.总结

aop是面向切面编程,普通程序由上而下正常执行,aop的程序执行是先执行到目标对象的目标方法中,如果连接点上由前置通知,则先执行前置通知再执行目标方法,最后如果目标方法有后置通知则最后执行后置通知代码,不管是前置通知,后置通知,环绕通知,异常通知,过滤通知,代码都是非业务核心代码,如日志、事务的管理(开启、提交、回滚)         

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

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

相关文章

udp与can通信的选择与比较

UDP&#xff08;用户数据报协议&#xff09;和CAN&#xff08;控制器局域网&#xff09;是两种不同的通信协议&#xff0c;它们在实时传递性上有一些区别。 UDP是一种无连接的传输协议&#xff0c;它提供了简单的、不可靠的数据传输。UDP不提供可靠性保证、流控制或重传机制。…

图解二叉树,拿下拿下!

图文详解二叉树 一、树形结构概念特性二、树形结构基本概念术语三、树的存储结构四、二叉树 概念与特性五、特殊的二叉树六、二叉树的性质七、二叉树的存储结构八、二叉树的基本操作1、二叉树的遍历&#xff08;1&#xff09;前中后序遍历&#xff08;2&#xff09;经典找序列&…

R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

探索性测试及基本用例

1 测试决策5要素 测试目标&#xff1a;所有的重要任务都完成了&#xff0c;而剩下没做的事情是比较次要的&#xff0c;我们做到这一点就可以尽早尽可能地降低发布风险。 测试方法&#xff1a;测试是一个不断抉择的过程&#xff0c;测试人员必须理解运行测试用例时和分析现有信…

自定义表格组件:实现表格中有固定列的功能逻辑

目录 1&#xff0c;效果图2&#xff0c;实现思路3&#xff0c;实现方式 1&#xff0c;效果图 可以拖动纵向滑块&#xff0c;最左边一列固定住。 以同样的道理&#xff0c;可以在右面固定一列 2&#xff0c;实现思路 作为一个table组件&#xff0c;要接受父组件中的对table的…

鸿蒙3.1 设备管理DeviceManager

介绍 DeviceManager组件在OpenHarmony上提供账号无关的分布式设备的认证组网能力,并为开发者提供了一套用于分布式设备间监听、发现和认证的接口。 其组成及依赖如下所示: 总结 设备管理模块其实就是软总线的包皮服务。目前权限都是控制系统uid,但是根据官方介绍,后续可…

webservice请求数据时找不到类com/sun/tools/internal/xjc/api/XJC

错误信息描述&#xff1a; java.lang.IllegalStateException: Unable to create schema compilerat org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompilerWithDefaultAllocator(JAXBUtils.java:744)at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createSch…

Spring 自定义命名空间并解析 NameSpaceHandler

Spring 自定义命名空间解析器 1.主要步骤 主要有以下四步&#xff1a; 编写Schema文件自定义NameSpaceHandler 绑定命令空间自定义 BeanDefinitionParse 解析XML作为bd的配置元信息命名空间映射XML 2.代码实现 需要注意的时&#xff0c;把 spring.handlers 文件与 spring.s…

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测 目录 分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测&#xff0c;运行环境Matlab2023b及以上…

实例039 始终在最上面的窗体

实例说明 Windows桌面上允许多个窗体同时显示&#xff0c;但是只有一个窗体能够得到焦点&#xff0c;当一个窗体得到焦点后在其上面的窗体会被得到焦点的窗体遮挡&#xff0c;得到焦点的窗体会显示在最上层&#xff0c;这样被覆盖的窗体就不能完全的显示给用户&#xff0c;如果…

Resolver error: Error: Connecting with SSH timed out

别忘了配置部门内部ip&#xff0c;才能访问服务器 windows卸载重装openssh 参考链接&#xff1a;安装 OpenSSH | Microsoft Learn

PHP自己的框架实现config配置层级存取(完善篇二)

1、实现效果 config(include_once $coreConfig); //加载配置文件config() //获取所有配置 config(DB_HOST) 获取配置 2、按层级配置文件加载&#xff0c;存取配置项 config,function.php function config($varNULL,$valueNULL){static $configarray();if(is_array($var)){…

阻塞IO、非阻塞IO和IO多路复用

文章目录 用户态和内核态操作系统角度的IOIO模型阻塞IO非阻塞IO&#xff08;NIO&#xff09;IO多路复用select 、poll和epoll 用户态和内核态 用户态也叫用户空间&#xff0c;内核态也叫内核空间。 操作系统为了保护系统的安全&#xff0c;都会划分出内核空间和用户空间。简单…

seata 的部署和集成

文章目录 seata的部署和集成一、部署Seata的tc-server1.下载2.解压3.修改配置4.在nacos添加配置5.创建数据库表6.启动TC服务 二、微服务集成seata1.引入依赖2.修改配置文件 TODO三、TC服务的高可用和异地容灾1.模拟异地容灾的TC集群2.将事务组映射配置到nacos3.微服务读取nacos…

PHP加密与安全的最佳实践

PHP加密与安全的最佳实践 概述 在当今信息时代&#xff0c;数据安全是非常重要的。对于开发人员而言&#xff0c;掌握加密和安全的最佳实践是必不可少的。PHP作为一种常用的后端开发语言&#xff0c;提供了许多功能强大且易于使用的加密和安全性相关函数和类。本文将介绍一些P…

vue动态修改audio地址

问题&#xff1a;点击后替换url地址&#xff0c;实现了&#xff0c;但是播放器依旧没有反应。 解决&#xff1a;vue中动态替换只是替换了地址&#xff0c;并没有告诉audio标签是否要执行&#xff0c;执行什么操作。要load后才能让它知道&#xff0c;是在喊他&#xff0c;他需求…

geacon_pro配合catcs4.5上线Mac、Linux

我的个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5&#xff0c;最新版解压密码见&#xff1a;https://www.nctry.com/2708.html geacon_pro: https://github.com/testxxxzzz/geacon_pro BeaconTool.jar: https:/…

工业用故障电弧探测器的设计与应用

安科瑞虞佳豪 壹捌柒陆壹伍玖玖零玖叁 故障电弧产生的原因---绝缘破损 原因二&#xff1a;线路绝缘破损&#xff0c;导致相间并联故障电弧及对地故障电弧 (1)电气线路施工时未按规范使用套管等保护措施&#xff1b; (2)野蛮施工等施工不当导致线路绝缘皮破损&#xff1b; …

基于web的人力资源管理系统/基于java的OA系统

摘 要 人力资源管理系统是现代企业的核心内容。随着计算机信息技术的高速发展电子商务模式的空前盛行&#xff0c;企业之间的竞争也从有形的经济市场转向了网络。开发以计算机技术、网络技术、信息技术支持的现代人力资源管理系统&#xff0c;既能提高人力资源管理的技术含量和…

云上社群学习系统部分接口设计详解与测试

目录 一、项目简介 1. 使用统一返回格式&#xff0b;全局错误信息定义处理前后端交互时的返回结果 2&#xff0e;使用ControllerAdviceExceptionHandler实现全局异常处理 3&#xff0e;使用拦截器实现用户登录校验 4. 使用MybatisGeneratorConfig生成常的增删改查方法 5. …