上一篇我们介绍Spring AOP的注解的配置,也叫做Java Config。今天我们看看比较传统的xml的方式如何配置AOP。整体的场景我们还是用原来的,“我穿上跑鞋”,“我要去跑步”。Service层的代码我们不变,还是用原来的,如下:

@Service
public class MyService {
public void gotorun() {
System.out.println("我要去跑步!");
}
}

再看看上一篇中的MyAspect代码,里边都是使用注解配置的,我们AOP相关的配置全部删除掉,只留下“我床上跑鞋“这样一个方法,如下:

public class MyAspect {
public void putonshoes() {
System.out.println("我穿上跑步鞋。");
}
}

类中没有任何的注解,我们将全部通过xml的方式配置AOP。首先,我们要在xml中引入aop的schema,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>

有了aop的schema,我们就可以使用Spring的aop的标签了,我们先将MyAspect实例化,因为我们的通知方法”我穿上跑鞋“在这个类中,如下:

<bean id="myAspect" class="com.example.springaopdemo.aspect.MyAspect" />

其中,id我们配置为myAspect。然后,我们就要配置<aop:config>了,这个标签说明这是一段aop配置,具体的aop内容都在这个标签内,如下:

<aop:config proxy-target-class="true">
……
</aop:config>

其中,我们还可以配置proxy-target-class这个属性,还记得这个属性是什么意思吗?对了,它代表着是否使用CGLIB代理,由于我们项目引入的依赖是spring-boot-starter-aop,默认是使用CGLIB的,所以这里配置不配置都可以。

然后在里边我们配置切面<aop:aspect>,它标识着这是一个切面配置,在标签里还要指定我们的切面的bean,也就是myAspect,如下:

<aop:aspect id="aopAspect" ref="myAspect">
……
</aop:aspect>

切面的id叫做aopAspect,ref指定我们切面的bean,就是前面实例化的myAspect。好了,切面就配置好了,然后就是切点和通知。切点和通知的配置一定要在<aop:aspect>内,说明这个切点和通知属于当前这个切面的。

先来看看切点<aop:pointcut>的配置吧,如下:

<aop:pointcut id="pointcut"
expression="execution(* com.example.springaopdemo.service.*.*(..))">
</aop:pointcut>

是不是很熟悉,我们看到了匹配方法的表达式。同样,我们要给切点定义一个id叫做pointcut,然后expression就是匹配的表达式,这个和上一篇是一样的,没有区别。在这里,我们还是匹配service包下的所有类的所有方法。好了,到这里切点就配置完成了。

最后,再来看看通知,通知是和<aop:pointcut>并列的,都在<aop:aspect>内,具体如下:

<aop:before method="putonshoes" pointcut-ref="pointcut"></aop:before>

通知的5种类型,分别对应着5个不同的标签,在这里我们还是使用前置通知<aop:before>,在标签的内部,要指定它对应的切点,pointcut-ref="pointcut",切点我们指定前面配置的,id是pointcut。然后就要指定方法method了,这个方法是哪个类中的方法呢?还记得我们再配置<aop:aspect>时指定的bean吗?ref指定了myAspect,那么method指定的方法就是myAspect这个bean中的方法。这里我们配置putonshoes方法。

好了,到这里,aop的配置就全部配置完了,我们看一下全貌吧,

<bean id="myAspect" class="com.example.springaopdemo.aspect.MyAspect" />

<aop:config proxy-target-class="true">
<aop:aspect id="aspect" ref="myAspect">
<aop:pointcut id="pointcut"
expression="execution(* com.example.springaopdemo.service.*.*(..))">
</aop:pointcut>
<aop:before method="putonshoes" pointcut-ref="pointcut"></aop:before>
</aop:aspect>
</aop:config>

最后,我们在SpringBoot的启动类中,使用@ImportResource("spring-aop.xml") 引入这个xml文件,如下:

@SpringBootApplication
@ImportResource("spring-aop.xml")
public class SpringAopDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAopDemoApplication.class, args);
}
}

测试类的程序和上一篇是一致,没有变化,如下:

@SpringBootTest
class SpringAopDemoApplicationTests {
@Autowired
private MyService myService; @Test
public void testAdvice() {
myService.gotorun();
}
}

运行一下看看结果,

我穿上跑步鞋。
我要去跑步!

没有问题,符合预期。

在上一篇中,我们可以使用简单的配置,也就是不配置切点,在通知中直接配置匹配表达式,如果忘记的同学可以翻一翻上一篇的内容。在xml的aop配置中,也是可以省略掉切点pointcut的配置的,我们在通知中,直接配置表达式,如下:

<aop:config proxy-target-class="true">
<aop:aspect id="aspect" ref="myAspect">
<aop:before method="putonshoes"
pointcut="execution(* com.example.springaopdemo.service.*.*(..))">
</aop:before>
</aop:aspect>
</aop:config>

是不是比前面的配置看起来清爽一些了。小伙伴们自己运行一下吧,结果是没有问题的。

好了,Spring AOP的Java Config和Schema-based 两种的方式的配置都介绍完了。我们拓展一下思维,Spring的事务管理也是AOP吧,在方法执行之前打开事务,在方法执行后提交事务。但是大家有没有留意,Spring的事务配置和咱们的AOP配置是不一样的,这是为什么呢?咱们下一篇再聊吧。

温故知新——Spring AOP(二)的更多相关文章

  1. 代理模式及Spring AOP (二)

    一.Spring AOP   1.1 Spring AOP 底层还是用的动态代理.如果目标对象所对应的类有接口,spring就用jdk生成代理对象: 如果目标对象所对应的类没有接口,spring就用C ...

  2. Spring AOP(二)--注解方式

    本文介绍通过注解@AspectJ实现Spring AOP,这里要重点说明一下这种方式实现时所需的包,因为Aspect是第三方提供的,不包含在spring中,所以不能只导入spring-aop的包,为了 ...

  3. 温故知新——Spring AOP

    Spring AOP 面向切面编程,相信大家都不陌生,它和Spring IOC是Spring赖以成名的两个最基础的功能.在咱们平时的工作中,使用IOC的场景比较多,像咱们平时使用的@Controlle ...

  4. Spring AOP (二)

    下面介绍@AspectJ语法基础 一.切点表达式函数 AspectJ的切点表达式由关键字和操作参数组成,如execution(* greetTo(..)) 的切点表达式,execution为关键字,而 ...

  5. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  6. Spring技术内幕:Spring AOP的实现原理(二)

    **二.AOP的设计与实现 1.JVM的动态代理特性** 在Spring AOP实现中, 使用的核心技术时动态代理.而这样的动态代理实际上是JDK的一个特性.通过JDK的动态代理特性,能够为随意Jav ...

  7. spring学习(二) ———— AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  8. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  9. spring AOP 之二:@AspectJ注解的3种配置

    @AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...

随机推荐

  1. 线程_GIL最简单的例子

    #解决多进程死循环 import multiprocessing def deadLoop(): while True: print("Hello") pass if __name ...

  2. PHP date_offset_get() 函数

    ------------恢复内容开始------------ 实例 返回奥斯陆(在欧洲挪威)冬天和夏天相对于 UTC 的以秒计的时区偏移量: <?php$winter=date_create(& ...

  3. CF321E Ciel and Gondolas Wqs二分 四边形不等式优化dp 决策单调性

    LINK:CF321E Ciel and Gondolas 很少遇到这么有意思的题目了.虽然很套路.. 容易想到dp \(f_{i,j}\)表示前i段分了j段的最小值 转移需要维护一个\(cost(i ...

  4. 4.28 省选模拟赛模拟赛 最佳农场 二维卷积 NTT

    第一次遇到二维卷积 不太清楚是怎么做的. 40分暴力比对即可. 对于行为或者列为1时 容易想到NTT做快速匹配.然后找答案即可. 考虑这是一个二维的比对过程. 设\(f_{i,j}\)表示以i,j为右 ...

  5. Electron~增量更新

    增量更新说明文档 English Version 提前准备 准备本地或者远程服务器或者远程静态文件url npm i -g http-server cd yourFileFolder // 进入任意文 ...

  6. AsyncTask被废弃了,换Coroutine吧

    本文主要是学习笔记,有版权问题还请告知删文 鸣谢:guolin@第一行代码(第三版) 你是否也在最近的代码中看见了 AsyncTask 被一条横杠划掉了 这表明--他要被Google放弃了 Googl ...

  7. Springboot使用Shiro-整合Redis作为缓存 解决定时刷新问题

    说在前面 (原文链接: https://blog.csdn.net/qq_34021712/article/details/80774649)本来的整合过程是顺着博客的顺序来的,越往下,集成的越多,由 ...

  8. Linux命令持续学习

    1 基础命令 1 jps 查看后台运行的java相关的程序  jvm调优所有 2 ps -ef | grep java 查询后台运行的程序(通过关键字) 3 cd - 回到上一级目录 4 vim之后输 ...

  9. 前端面试 vue 部分 (5)——VUE组件之间通信的方式有哪些

    VUE组件之间通信的方式有哪些(SSS) 常见使用场景可以分为三类: 父子通信: null 父向子传递数据是通过 props ,子向父是通过 $emit / $on $emit / $bus Vuex ...

  10. jQuery 多库共存

    多库共存 问题概述         jQuery使用$作为标识符,随着jQuery的流行,其他js的库也会用$作为标识符,这样就会引起冲突         需要一个解决方案 让jQuery和其他的JS ...