SpringAOP应用(AspectJ)

Spring AOP 应用 AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往应用在权限校验、日志、事务控制、性能监控中。 阅读详情

任务需求

系统A的数据库中定义了一张document表,用来存放文档的基本信息,当用户对表数据执行增删改操作时,需要发送消息给系统B,通知其执行相应处理,消息内容包括文档变动类型和文档数据信息。

需求实现

我们能想到的最简单的处理方式如下:

修改数据和发送消息本是两个独立的功能,doAction方法却将其耦合在了一起,方法的处理暂时不存在任何问题,然而随着时间的推移,需求的变动,如果想要禁用消息就需要对业务层的代码进行修改,将sendMessage方法注释掉。

能否通过一种更为优雅的方式来避免硬编码情况的发生?

在上述处理方式中引入了服务容器的概念,消息服务相当于功能切面,而Spring框架相当于功能切面的容器。
doAction方法通过标签的方式来声明对消息服务的依赖,如果容器中含有消息服务,则在修改数据的同时触发消息,如果没有,则只完成修改数据的处理操作。
这样处理的好处是服务之间的耦合度变的更加松散,可通过服务插拔的处理方式来实现业务需求的变动,如果想要禁用消息,只需要将消息切面从Spring容器中移除即可,而不用修改任何代码。

实现细节

首先定义出消息服务切面
切面由切入点和通知构成,AspectJ中通过@Aspect标签来声明
@Aspect
public class SendMessageAdvice {
	private static final Logger LOG = LoggerFactory.getLogger(SendMessageAdvice.class);
	@Pointcut("@annotation(org.chen.aopdemo.SendMessage)")
	public void send() {}
	@Around("send()")
	public void doSendMessage(final ProceedingJoinPoint pjp) throws Throwable {
		pjp.proceed();//执行被拦截的方法
		//获取所拦截的方法名
		MethodSignature msig=(MethodSignature) pjp.getSignature();
		String name = msig.getName();
        Class<?>[] parameters = msig.getParameterTypes();
        Object target = pjp.getTarget();
        Method method = target.getClass().getMethod(name, parameters);//获取拦截的method
        //方法是否使用了泛型参数
        if(method.isBridge()){
        	Class<?> erasedParam=null;
            Class<?> targetParam=null;
        	Annotation[] annotations=target.getClass().getAnnotations();
        	first:for(Annotation annotation:annotations){
        		if(annotation instanceof BridgeMethodMappings){
        			BridgeMethodMappings mappings=(BridgeMethodMappings) annotation;
        			for(BridgeMethodMapping mapping:mappings.value()){
        				if(mapping.methodName().equals(name)){
        					erasedParam=mapping.erasedParamTypes()[0];
        					targetParam=mapping.targetParamTypes()[0];
        					break first;
        				}
        			}
        		}
        	}
        	//将泛型参数替换成指定参数
        	for(int i=0;i<parameters.length;i++){
        		if(parameters[i].equals(erasedParam)){
        			parameters[i]=targetParam;
        		}
        	}
        	//重新得到方法声明
        	method = target.getClass().getMethod(name, parameters);//获取拦截的method
        }
        SendMessage sendMsg=method.getAnnotation(SendMessage.class);//获取方法所声明的SendMessage标签
        SignalType singleType=sendMsg.single();//获取标签声明的消息类型
		Annotation[][] annotations=method.getParameterAnnotations();
		Integer msgDataIndex=null;
		//获取含有MessageData标签的方法参数索引
		first:for(int i=0;i<annotations.length;i++){
			Annotation[] paramAnnotation=annotations[i];
			for(int j=0;j<paramAnnotation.length;j++){
				if(paramAnnotation[j] instanceof MessageData){
					MessageData msgData=(MessageData) paramAnnotation[j];
					if(msgData.order()==0){
						msgDataIndex=new Integer(i);
						break first;
					}
				}
			}
		}
		if(msgDataIndex!=null){
			Serializable obj=(Serializable) pjp.getArgs()[msgDataIndex];//获取方法参数值
			doSendMessage(singleType,obj);//执行发送消息操作,传递消息类型和消息数据
			LOG.info("发送消息成功,消息类型:"+singleType.getOp()+",消息数据:"+obj);
		}
	}
}
@Pointcut标签声明了消息服务的切入点,如果方法声明了SendMessage标签则拦截该方法执行发送消息的处理。
@Around标签声明了通知,方法中描述了发送消息的具体操作。
然后将消息服务切面注入到Spring容器中
在Spring配置文件中添加如下配置
<aop:aspectj-autoproxy />
<bean id="sendMessage" class="cn.com.gei.krp.ecm.core.index.jms.SendMessageAdvice">
	<property name="jmsurl" value="tcp://user-df29b9c8dc:61616?jms.useAsyncSend=true" />
</bean>
最后在DocumentDao的相关方法中对消息服务声明依赖(通过SendMessage标签)
@BridgeMethodMappings({
	@BridgeMethodMapping(methodName="delete",erasedParamTypes={Serializable.class},targetParamTypes={String.class}),
	@BridgeMethodMapping(methodName="update",erasedParamTypes={Object.class},targetParamTypes={Document.class}),
	@BridgeMethodMapping(methodName="insert",erasedParamTypes={Object.class},targetParamTypes={Document.class}),
})
public class DocumentDao extends 
	SimpleHibernateDao<Document, String> implements IDocumentDao{
	@Override
	@SendMessage(type=MessageType.deleteDocument)
	public void delete(@MessageData String id) {
		super.delete(id);
	}
	@Override
	@SendMessage(type=MessageType.updateDocument)//声明消息服务依赖
	public void update(@MessageData Document entity) {
		super.update(entity);
	}
	@Override
	@SendMessage(type=MessageType.addDocument)
	public void insert(@MessageData Document entity) {
		super.insert(entity);
	}
}
这样,在执行document的增删改操作时,如果Spring声明了消息服务,则执行发送消息的处理,否则只执行原操作。

Spring AOP应用 主要是利用Spring AOP实现动态数据源,和数据缓存操作。 立即下载

相关推荐

spring 应用aop 实例

spring 采用aop 的实例

SpringAOP实际应用

因为需要获取到全局的代码异常,所有就不需要通过自定义注解方式定义切入点,要将所有的类,方法都囊括进来*.*executtion。

小小小猿 338

HyperLPR3车牌识别-Android-SDK光速部署与使用

基于深度学习高性能中文车牌识别 High Performance Chinese License Plate Recognition Framework.快速部署AndroidSDK

tunm 6121

Spring AOP应用场景深度解析:从核心原理到六大实战案例

本文系统解析Spring AOP的核心机制与高频应用场景,涵盖日志记录、权限校验、事务管理等六大经典案例,并深入实战缓存优化、API调用统计、滑动窗口限流等高级技巧。通过自定义注解与环绕通知设计,助你快速掌握AOP在复杂业务中的模块化实践,提升代码可维护性与开发效率。适合中高级开发者快速突破AOP落地难点。

Zyw907155124的博客 4803

Unity Android平台下插件/SDK开发通用流程

本文主要面向对Android开发不甚了解的Unity开发者,介绍了基于最新的Android Studio的标准Android开发环境与项目结构的配置流程,在此基础上,开发者可以快速的进行SDK的接入与插件的开发。

ZhangDi2017的博客 1万+

OpenEarthMap 与 xBD 数据集合并

整合好的数据:链接: https://pan.baidu.com/s/1uJ_Zg6n-s3u1D49OW52D7Q?pwd=2vwx 提取码: 2vwx完整整合步骤与代码如下。

qq_60293814的博客 1597

Spring(AOP)的使用方法

完成日志记录功能,当用户进行数据库增、删、改的时候记录操作日志。}}

m0_74795259的博客 5437

手把手教你用STM32的ADC读取PT100模块,实现高精度温度采集(附完整代码)

本文详细介绍了如何利用STM32的ADC模块读取PT100温度传感器信号,实现高精度温度采集系统。从硬件选型、ADC配置校准到温度计算算法和软件滤波技术,提供完整的实现方案和优化技巧,帮助工程师快速构建稳定可靠的温度监测系统。

weixin_29185199的博客 349

Spring之AOP

2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法进行增强,但是因为采用的是继承,所以该类或方法最好不要声明为final,对于final类或方法,是无法继承的。getAdvicesAndAdvisorsForBean方法,Advisor(执行者)包括Advisors(执行的方法)和Pointcut (切面)1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类。Spring中AOP底层的实现是基于动态代理进行实现的。常见的动态代理技术有两种:JDK的动态代理和CGLIB。

weixin_43653230的博客 218

科研绘图系列:R语言绘制世界地图数据分布(world map)

科研绘图系列:R语言绘制世界地图数据分布(world map)

专注生信领域 529

《YOLOv8:从入门到实战》专栏介绍 & 专栏目录

本专栏涵盖了丰富的YOLOv8算法从入门到实战系列教程,专为学习YOLOv8的同学而设计,堪称全网最详细的教程!🌈🌈🌈

小哥谈 6491

AspectJ框架的解析及应用

运行类->右键单击->Run As->Run.,可以在弹出的Run设置窗口设置该类的各项运行属性,切换到ArgumentsTab页,在VM arguments中通过-javaagent指定Aspect织入器类包。相比于加载时织入和运行时织入,编译时织入在编译阶段就将切面织入到目标类的字节码中,这样在程序运行时就无需再进行切面的织入操作。LTW是一种在类加载时织入切面的方式。与CTW和RTW相比,加载时织入提供了更大的灵活性,并且可以在不修改原始源代码的情况下,将切面逻辑应用到已编译的类中。

weixin_64901910的博客 1098

【OpenCV实战】简洁易懂的车牌号识别Python+OpenCV实现“超详解”(含代码)

简洁易懂的车牌号识别Python实现(含代码)1、整体思路2、代码详解 1、整体思路 2、代码详解

qq_40784418的博客 9万+

Spring AOP与AspectJ的对比及应用

1 简介 AOP,即面向切面编程是很常用的技术,特别是在Java Web开发中。而最流行的AOP框架分别是Spring AOP和AspectJ。 2 Spring AOP vs AspectJ Spring AOP是基于Spring IoC实现的,它解决大部分常见的需求,但它并不是一个完整的AOP解决方案。对于非Spring容器管理的对象,它更没有办法了。而AspectJ旨在提供完整的AOP方案,因此也会更复杂。 2.1 织入方式 两者织入方式有极大的不同,这也是它们的本质区别,它们实现代理的方式不同。 A

南瓜慢说 718

建行报专版报道建设银行金融科技发展历程

经过十多年的建设,总行前中后台部门都有了自己的业务系统,但系统“部门”特征显著,渠道、客户、产品的横向整合不足,产品系统层次化、结构化、参数化程度不高,渠道支持产品快速部署以及跨渠道服务能力不足,管理分析类系统建设相对滞后,系统较弱的可扩展能力在应对高速增长的交易量时已疲态尽显,同时安全稳定运行的压力和风险日益积聚。站在新的历史起点上,科技条线将聚焦主责主业,完善信息科技管理体系,紧紧围绕安全生产中心任务,持续推动技术能力复用共享和自主可控,为全行做好金融五篇大文章,推动业务高质量发展提供技术支撑。

银行信息系统应用架构详解 386

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

简单说说SpringAOP与Aspectj的不同,以及使用SpringAOP所需的最小jar依赖

首先,SpingAop与Aspectj在面向切面编程是关注的点不同。 Spring AOP的目的并不是为了提供最完整的AOP实现(虽然Spring AOP具有相当的能力);而是为了要帮助解决企业应用中的常见问题,提供一个AOP实现与Spring IOC之间的紧密集成,能够处理业务中的横切关注点。 Aspectj提供了非常完善的AOP能力,几乎能在java ...

Snower08的博客 1466

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Spring AOP 和 AspectJ 之间的差别

Spring AOP 和 AspectJ 之间的差别使用AOP的优势相同点与不同点相同点不同点1、应用场景不同(1)Spring AOP的实现都是在运行时进行织入的,而且只能针对方法进行AOP,无法针对构造函数、字段进行AOP。AspectJ可以在编译成class时就织入,还提供了后编译器织入和类加载期织入。2、选用原则(1)Spring Bean 中的bean无final修饰符,或者相似的方法也没有标以static或final修饰符时,使用Spring AOP。(2)Spring Bean 中的bean有

xiashenbao的博客 564

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

比较Spring AOP和AspectJ

1. 介绍 当前有多个可用的AOP库,这些库必须能够回答许多问题: 它与我现有的或新的应用程序兼容吗? 在哪里可以实施AOP? 它与我的应用程序集成的速度有多快? 性能开销是多少? 在本文中,我们将着眼于回答这些问题,并介绍Spring AOP和AspectJ(这两种最流行的Java AOP框架)。 2. AOP 概念 在开始之前,让我们对术语和核心概念进行快速的高层次审查: 切面–一种标准代码/功能,分散在应用程序的多个位置,通常与实际的业务逻辑(例如,事务管理)不同。每个方面都专注于特定的跨领域功

qq_43842093的博客 4754

何时使用SpringAOP与aspectJ

Spring AOP致力于提供一种能够与Spring IoC紧密集成的面向方面框架的实现,以便于解决在开发企业级项目时面临的常见问题。明确你在应用横切关注点(cross-cutting concern)时(例如事物管理、日志或性能评估),需要处理的是Spring beans还是POJO。如果正在开发新的应用,则选择Spring AOP就没有什么阻力。但是如果你正在维护一个现有的应用(该应用并没有使

zxq520131422222的博客 551

基于AspectJ的SpringAOP开发

1级标题 2级标题 3级标题 四级标题 五级标题 六级标题

qq_41822751的博客 280

一文知晓:AspectJ,SpringAOP,cglib,动态代理究竟有啥区别

一切源于需求: 我只想写业务流程代码,不想管日志,权限,事务等业务无关的东西,怎么办? 要是我只写业务代码,想要其他代码的时候有人帮我写就好了。。。 于是,代理(代码小蜜)就出现了 代理有好多种实现方式呢: AspectJ 首先,这是一种语言,类似于Java语言,与Java无缝兼容,而且像Java自带jvm一样,这种语言也自带编译器acj。 从上图可以看出,AspectJ在...

xiaoxiaojavacsdn的博客 1267

AOP的两种实现-Spring AOP以及AspectJ

在接触Spring以及种类繁多的Java框架时,很多开发人员(至少包括我)都会觉得注解是个很奇妙的存在,为什么加上了@Transactional之后,方法会在一个事务的上下文中被执行呢?为什么加上了@Cacheable之后,方法的返回值会被记录到缓存中,从而让下次的重复调用能够直接利用缓存的结果呢? 随着对AOP的逐渐应用和了解,才明白注解只是一个表象,在幕后Spring AOP/AspectJ做...

易梦南蝶的博客 397

spring讲解五:springAop 、Aop、AspectJ他们的关系是什么? 他们的核心又是什么 ?

首先: AOP是一种思想,是一种面向切面编程的思想,AOP的主要作用就是,告诉我们可以通过动态代理的方式,织入一段代码到已经写到另一段代码中去。 再说: SpringAop 和 AspectJ 都是两个框架,它主要就是通过AOP的思想,来实现面向切面编程。 因为动态代理的方式,不止一种,所以也出现了两个框架,其实实现的作用都是一样的。 他们的核心就是: 动态代理。 最开始实...

chuxin_mm的博客 776

说说AOP、AspectJ、CGLIB ?它们有什么关系?

AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。AOP 实现...

hnjsjsac的博客 256

似懂非懂的 AspectJ

今天想和小伙伴们聊一下我们在使用 Spring AOP 时,一个非常常见的概念 AspectJ。

江南一点雨的专栏 452
上一篇: android应用之SQLite数据库
下一篇: android自定义分页组件
JavaMan_chen
博客等级 码龄19年 329粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值