Spring基于XML文件配置AOP

AOP

AOP,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,属性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程

AOP思想的实现方案:动态代理技术,在运行期间,对目标对象的方法进行增强,代理对象同名方法内可以执行原有逻辑的同时嵌入执行其他增强逻辑或其他对象的方法

下面是AOP的实现思想

创建增强类,编写前方法与后方法

public class MyAdvice {public void beforeAdvice(){System.out.println("执行增强前方法");}public void afterAdvice(){System.out.println("执行增前后方法");}
}

编写被增强类,并编写一个方法用于增强

public class UserServiceImpl implements UserService {@Overridepublic void show() {System.out.println("show...");}}

Bean后处理器去实现将Bean对象替换成代理类

public class MyBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {private ApplicationContext context;@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//对指定方法进行增强if (bean instanceof UserService) {//获取增强方法MyAdvice myAdvice = context.getBean(MyAdvice.class);Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {myAdvice.beforeAdvice();method.invoke(bean, args);myAdvice.afterAdvice();return proxy;}});return proxyInstance;}return bean;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}
}

XML文件配置如下 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"></bean><bean class="com.zmt.processor.MyBeanPostProcessor"/><bean class="com.zmt.advice.MyAdvice"/>
</beans>

执行测试代码

public class ApplicationTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserService userService = context.getBean(UserService.class);userService.show();}
}

执行结果如下 

这种实现方式存在两个问题,一个是需要被增强的Bean对象需要硬编码指定,其次是增强方法也是被写死的,如果需要修改被增强的类或是修改增强方法都需要修改代码。

那么我们在了解Spring中AOP时,需要先了解如下几个概念

目标对象

Taeget

被增强的方法所在的对象

代理对象

Proxy

对目标方法进行增强后的对象,客户端实际调用的对象

连接点

Joinpoint

目标对象中可以被增强的方法

切入点

Pointcut

目标对象中实际被增强的方法

通知\增强

Advice

增强部分的代码逻辑

切面

Aspect

增强和切入点的组合

织入

Weaving

将通知和切入点动态组合的过程

那么接下来给出基于XML的实现AOP的示例代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"/><!--将增强类交给Spring管理--><bean id="myAdvice" class="com.zmt.advice.MyAdvice"/><aop:config><!--配置切面表达式,指定需要被增强的方法--><aop:pointcut id="myPointcut" expression="execution(void com.zmt.service.impl.UserServiceImpl.show())"/><!--指定切点与哪些增强类结合--><aop:aspect ref="myAdvice"><aop:before method="beforeAdvice" pointcut-ref="myPointcut"/></aop:aspect></aop:config>
</beans>
public class UserServiceImpl implements UserService {@Overridepublic void show() {System.out.println("show...");}}
public class MyAdvice {public void beforeAdvice(){System.out.println("执行增强前方法");}public void afterAdvice(){System.out.println("执行增前后方法");}
}

测试代码如下

public class ApplicationTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserService userService = context.getBean(UserService.class);userService.show();}
}

运行结果如下

execution语法

execution([访问修饰符] 返回值类型 报名.类名.方法名(参数))

  • 访问修饰符可以省略不写
  • 返回值类型、某一级包名、类名、方法名可以使用 * 表示任意
  • 包名与类名之间使用单点 . 表示该包下的类,使用双点 .. 表示该包以及子包下的类
  • 参数列表可以使用双点 .. 表示任意参数

XML文件下通知的配置类型

通知名称

配置方式

执行时机

前置通知

< aop:before >

目标方法执行之前执行

后置通知

< aop:after-returning >

目标方法执行之后执行,目标方法异常时不再执行

环绕通知

< aop:around >

目标方法执行前后执行,目标方法异常时,环绕后方法不再执行

异常通知

< aop:after-throwing >

目标方法抛出异常时执行

最终通知

< aop:after >

不管目标方法是否有异常,最终都会执行

环绕通知需要将连接点传入,具体的增强类实现代码如下

public class MyAdvice {public void beforeAdvice(){System.out.println("执行增强前方法");}public void afterAdvice(){System.out.println("执行增前后方法");}public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕前通知。。。");Object proceed = joinPoint.proceed();System.out.println("环绕后通知。。。");return proceed;}
}

增强方法在被调用时,Spring可以为其传递一些必要参数

参数类型

作用

JoinPoint

连接点对象,任何通知都可以使用,可以获取当前目标对象,目标方法参数等信息

ProceedingJoinPoint

JoinPoint子类对象,主要是在环绕通知中执行proceed(),进而执行目标方法

Throwable

异常对象,使用在异常通知中,需要在配置文件中指出异常对象名称

除了上面实现AOP之外,基于XML文件配置的实现方式还存在另一种实现方式,通过实现接口来表示该增强类的具体操作。

public class MyAdvice2 implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("环绕前通知。。。。");Object res = invocation.getMethod().invoke(invocation.getThis(), invocation.getArguments());System.out.println("环绕后通知。。。。");return res;}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"/><bean id="myAdvice2" class="com.zmt.advice.MyAdvice2"/><aop:config><aop:pointcut id="myPointcut" expression="execution(void com.zmt.service.impl.UserServiceImpl.show())"/><!-- 指定增强类与切点 --><aop:advisor advice-ref="myAdvice2" pointcut-ref="myPointcut"/></aop:config>
</beans>

注意:一个增强类可以实现多个Advice接口

AOP配置的两种语法形式不同点

语法形式不同:

  • advisor是通过实现接口来确认通知的类型
  • aspect是通过配置确认通知的类型,更加灵活

可配置的切面数量不同:

  • 一个advisor只能配置一个固定通知和一个切点表达式
  • 一个aspect可以配置多个通知和多个切点表达式任意组合

使用场景不同:

  • 允许随意搭配情况下可以使用aspect进行配置
  • 如果通知类型单一、切面单一的情况下可以使用advisor进行配置
  • 在通知类型已经固定,不用人为指定通知类型时,可以使用advisor进行配置

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kafka常见问题处理

1. 如何防⽌消息丢失 在生产者层面&#xff0c;我们有个ack参数确认机制 设置成-1&#xff0c;也就是副本全部同步了leader才发送ack&#xff0c;这样确保leader和副本挂掉只剩一个还能 保证消息不丢失 消费者&#xff1a; 把⾃动提交改成⼿动提交 2. 如何防⽌重复消费 在…

飞天使-linux操作的一些技巧与知识点3

http工作原理 http1.0 协议 使用的是短连接&#xff0c;建立一次tcp连接&#xff0c;发起一次http的请求&#xff0c;结束&#xff0c;tcp断开 http1.1 协议使用的是长连接&#xff0c;建立一次tcp的连接&#xff0c;发起多次http的请求&#xff0c;结束&#xff0c;tcp断开ngi…

【小米电脑管家】安装使用教程--非小米电脑

安装说明功能体验下载资源 Xiaomi HyperOS发布后&#xff0c;小米妙享电脑端独立版本也走向终点&#xff0c;最新的【小米电脑管家】将会内置妙享实现万物互联。那么本篇文章将分享非小米电脑用户如何绕过设备识别验证安装使用【小米电脑管家】实现万物互联 安装说明 1.解压文…

【探索Linux】—— 强大的命令行工具 P.21(多线程 | 线程同步 | 条件变量 | 线程安全)

阅读导航 引言一、线程同步1. 竞态条件的概念2. 线程同步的概念 二、条件变量1. 条件变量函数⭕使用前提&#xff08;1&#xff09;初始化条件变量&#xff08;2&#xff09;等待条件满足&#xff08;3&#xff09;唤醒等待pthread_cond_broadcast()pthread_cond_signal() &…

windows安装protoc、protoc-gen-go、protoc-gen-go-grpc

文章目录 一、 protoc二、protoc-gen-go三、protoc-gen-go-grpc 一、 protoc 1&#xff0c;下载&#xff1a;https://github.com/google/protobuf/releases 下载对应的protoc&#xff0c;注意选择windows 2&#xff0c;下好之后解压就行&#xff0c;然后把bin目录加入到环境…

JAVA多线程

线程是相当于独立的&#xff0c;在线程中的也是句不变量&#xff0c;除非i将变量定义一在类中或者调用其他类中的方法&#xff0c;来实现公用。 多线程的创建&#xff1a;有两种方案进行创建多线程 Thread对象提供的多线程(无返回值结果void)&#xff1a; main方法默认是一条主…

【出现模块node_modules里面包找不到】

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 一、出现的问题二、解决办法三、其它可供参考 一、出现的问题 在本地运行 npm run docs:dev之后&#xff0c;出现 Error [ERR_MODULE_NOT_FOUND]: Cannot find package Z:\Blog\docs\node_modules\htmlparser2\ imported from Z:\Blo…

坚鹏:中国建设银行商业银行场景生态搭建与GBC联动培训

中国建设银行股份有限公司是一家中国领先的大型商业银行&#xff0c;总部设在北京&#xff0c;其前身中国人民建设银行成立于1954年10月。2005年10月在香港联合交易所挂牌上市&#xff0c;2007年9月在上海证券交易所挂牌上市。建设银行为客户提供公司金融业务、个人金融业务、资…

【MATLAB】基于EMD分解的信号去噪算法(基础版)

代码操作 【MATLAB】基于EMD分解的信号去噪算法&#xff08;基础版&#xff09; 代码的主要内容 基于EMD&#xff08;经验模态分解&#xff09;的信号去噪算法通常可以结合相关系数、信号的熵值或者方差贡献率来完成去噪处理。这些指标可以用于确定阈值&#xff0c;从而对信号…

MVC、MVP、MVVM模式的区别

前言&#xff1a;这三个表现层框架设计模式是依次进化而形成MVC—>MVP—>MVVM。在以前传统的开发模式当中即MVC模式&#xff0c;前端人员只负责Model&#xff08;数据库&#xff09;、 View&#xff08;视图&#xff09;和 Controller /Presenter/ViewModel&#xff08;控…

地址栏不安全提示

在使用浏览器时访问网站的时候&#xff0c;我们可能会遇到地址栏提示不安全的情况。这种情况通常都是是由于未安装有效SSL证书或者网站SSL证书过期等原因导致的。本文将介绍如何处理地址栏提示不安全的问题&#xff0c;以确保我们的上网安全。 1&#xff0c;缺少SSL证书&#x…

唱响主旋律——建行江门市分行推动服务实体经济高质量发展

建行江门市分行主动对接当地战略部署&#xff0c;在侨乡热土踏歌而行&#xff0c;全力当好服务实体经济的主力军和维护金融稳定的压舱石&#xff0c;在助力再造一个现代化新江门上贡献建行力量。 输血实体 为实体经济服务是金融的天职。建行江门市分行积极发挥在重大基建领域…

[oeasy]python0002_终端_CLI_GUI_编程环境_游戏_真实_元宇宙

回忆 上次 了解了 python 语言的特点 历史悠久功能强大深受好评已成趋势 3大主流操作系统 macwindowslinux 我们 选择 linux 作为基础系统 为什么选择 黑乎乎的命令行界面呢&#xff1f;&#x1f914; GUI vs CLI 个人电脑 用图标和菜单组成 图形界面(GUI) Graphic User I…

tamcat乱码

学习springmvc时tamcat乱码 ①、启动时tomcat控制台乱码 解决方法是&#xff1a;1、先把idea设置里的默认字节码改成utf-8 ​ 2、把idea显示编码改成utf-8&#xff0c;在末尾加上&#xff08; -Dfile.encodingUTF-8&#xff09; ​ 3、最后重启idea 加上这个 -Dfile.encodingU…

异步回调模式

异步回调 所谓异步回调&#xff0c;本质上就是多线程中线程的通信&#xff0c;如今很多业务系统中&#xff0c;某个业务或者功能调用多个外部接口&#xff0c;通常这种调用就是异步的调用。如何得到这些异步调用的结果自然也就很重要了。 Callable、Future、FutureTask publi…

【EI会议征稿中】第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)

第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#xff09; 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 第二届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2023&…

Shell数组函数:数组——数组和循环(四)

使用数组统计&#xff0c;用户shell的类型和数量 一、脚本编辑 [root192 ~]# vim shell.sh #!/bin/bash declare -A shells while read ii dotypeecho $ii | awk -F: {print $7}let shells[$type] done < /etc/passwdfor i in ${!shells[]} doecho "$i: ${shells[$i]…

SpringSecurity6 | 自定义登录页面

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…

SAP UI5 walkthrough step7 JSON Model

这个章节&#xff0c;帮助我们理解MVC架构中的M 我们将会在APP中新增一个输入框&#xff0c;并将输入的值绑定到model&#xff0c;然后将其作为描述&#xff0c;直接显示在输入框的右边 首先修改App.controllers.js webapp/controller/App.controller.js sap.ui.define([&…

JAVA使用POI向doc加入图片

JAVA使用POI向doc加入图片 前言 刚来一个需求需要导出一个word文档&#xff0c;文档内是系统某个界面的各种数据图表&#xff0c;以图片的方式插入后导出。一番查阅资料于是乎着手开始编写简化demo,有关参考poi的文档查阅 Apache POI Word(docx) 入门示例教程 网上大多数是XXX…