Spring之AOP
这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
Spring的核心是控制反转(IoC)和面向切面(AOP)
前面我们已经了解了IOC,现在来了解什么是AOP!
一、AOP的概念
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
为什么说Spring是一个一站式的轻量级开源框架呢?JavaEE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。
• WEB层:SpringMVC
• 业务层:Spring的IoC
• 持久层:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久层框架)
Spring AOP 模块提供拦截器来拦截一个应用程序,例如,当执行一个方法时,你可以在方法执行之前或之后添加额外的功能。
如下图:
在我们的开发中:dao、service、controller、view层都可以认为是一个切面,**对象与对象之间,方法与方法之间,模块与模块之间都是一个个切面。**我们不改变源代码的情况下,在执行某个切面里的某个方法的时候,在后期开发想添加一些功能,改动源代码代价太大,那么我们就可以通过切入点表达式,指定拦截哪些类的哪些方法, 给指定的类在运行的时候植入切面类代码。这就是面向切面编程。下图也是一个实现的流程。
注意:AOP不是一种技术,实际上是编程的思想。
二、AOP组成
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
在我们开始使用 AOP 工作之前,让我们熟悉一下 AOP 概念和术语。这些术语并不特定于 Spring,而是与 AOP 有关的。
项 | 描述 |
---|---|
Aspect(切面) | 一个模块具有一组提供横切需求的 APIs。例如,一个日志模块为了记录日志将被 AOP 方面调用。应用程序可以拥有任意数量的方面,这取决于需求。 |
Join point(切入点) | 在你的应用程序中它代表一个点,你可以在插件 AOP 方面。你也能说,它是在实际的应用程序中,其中一个操作将使用 Spring AOP 框架。 |
Advice(通知) | 这是实际行动之前或之后执行的方法。这是在程序执行期间通过 Spring AOP 框架实际被调用的代码。 |
Pointcut(切入短) | 这是一组一个或多个连接点,通知应该被执行。你可以使用表达式或模式指定切入点正如我们将在 AOP 的例子中看到的。 |
Introduction | 引用允许你添加新方法或属性到现有的类中。 |
Target object(目标) | 被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。也称为被通知对象。 |
Weaving(织入) | Weaving 把方面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时,类加载时和运行时完成。 |
通知的类型
SpringAOP中,通过Advice可以使用下面提到的五种通知工作:
通知 | 描述 |
---|---|
前置通知 | 在一个方法执行之前,执行通知。 |
后置通知 | 在一个方法执行之后,不考虑其结果,执行通知。 |
返回后通知 | 在一个方法执行之后,只有在方法成功完成时,才能执行通知。 |
抛出异常后通知 | 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 |
环绕通知 | 在建议方法调用之前和之后,执行通知。 |
三、AOP的实现
- 通过 Spring API 实现
- 自定义类来实现Aop
- 通过注解实现
项目结构:
需要导入一个AOP织入依赖包!
1 | xml复制代码<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> |
1、通过 Spring API 实现
编写业务接口
1 | java复制代码public interface UserService { |
编写业务接口实现类
1 | java复制代码public class UserServiceImpl implements UserService{ |
编写两个日志增强类
前置增强
1 | java复制代码public class BeforeLog implements MethodBeforeAdvice { |
后置增强
1 | java复制代码public class AfterLog implements AfterReturningAdvice { |
编写applicationContext.xml
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
这里用的是 通过类定义切点
拓展:execution表达式的使用:
详细的使用可以参照这篇博客execution表达式
测试类
1 | java复制代码public class Text { |
结果:
2、自定义类来实现Aop
自定义一个DiypointCut,写上自己想执行的方法
1 | java复制代码public class DiypointCut { |
编写applicationContext.xml
1 | xml复制代码 <!--第二种方式自定义实现--> |
测试类
1 | java复制代码public class Text { |
结果:
3、注解实现
编写AnnotationPointcut注解实现的增强类
1 | java复制代码@Aspect //标注这个类是一个切面 |
在Spring配置文件中,注册bean,并增加支持注解的配置
1 | xml复制代码 <!--第三种方式:注解实现--> |
测试类:
1 | java复制代码public class Text { |
结果:
学习一定要多看官方文档,多看源码,了解底层原理是怎么实现的,今日份学习!
本文转载自: 掘金