✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。
🍎个人主页:Hhzzy99
🍊个人信条:坚持就是胜利!
💞当前专栏:【Spring】
🥭本文内容:Spring框架中AOP的深入学习,带你搞透这门技术!
Spring
文章目录
前言
这篇文章是上一篇文章(IoC和DI)🚩的后续,感兴趣的朋友们可以去看看(●’◡’●)
AOP简介
什么是AOP?它的作用是什么?
上一篇文章中,我们在介绍Spring的时候说过,Spring有两个核心的概念,一个是IOC/DI
,一个是AOP
。IOC/DI
已经学习过了,
那么AOP
又是什么呢?
AOP(Aspect Oriented Programming) 面向切面编程,它是一种编程范式,指导开发者如何组织程序结构。我们学Java的都知道OOP
(Object Oriented Programming) 面向对象编程,它是一种编程思想,AOP
也是一种编程思想。
AOP
的作用是什么呢?
它的作用通俗点讲,就是在不惊动原来设计的基础上,对其进行功能上的增强。
AOP的核心概念
AOP的核心概念可以总结如下:
连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方
法、抛出异常、设置变量等
- 在SpringAOP中,可以理解为方法的执行
切入点(Pointcut): 匹配连接点的式子
- 在SpringAOP中,一个切入点可以描述一个具体方法,也可也匹配多个方法
- 一个具体的方法:如com.hzy.dao包下的BookDao接口中的无形参无返回值的save方法
- 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法
- 连接点范围要比切入点范围大,是切入点的方法也一定是连接点,但是是连接点的方法就不一定要被增强,所以可能不是切入点。
通知(Advice): 在切入点处执行的操作,也就是共性功能
- 在SpringAOP中,功能最终以方法的形式呈现
通知类: 定义通知的类
切面(Aspect): 描述通知与切入点的对应关系。
简单入门案例
我们先做一个简单案例来入门=》
设定: 在方法执行前输出当前系统时间
思路分析:
1.导入坐标(pom.xml)
2.制作连接点(原始操作,Dao接口与实现类)
3.制作共性功能(通知类与通知)
4.定义切入点
5.绑定切入点与通知关系(切面)
环境搭建
先创建一个maven环境(这个大家都会吧)
在pom.xml中添加Spring依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
添加BookDao
和BookDaoImpl
类
public interface BookDao {
public void save();
public void update();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println(System.currentTimeMillis());
System.out.println("book dao save ...");
}
public void update(){
System.out.println("book dao update ...");
}
}
然后创建Spring的配置类
@Configuration
@ComponentScan("com.hzy")
public class SpringConfig {
}
最后编写Application运行类
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = ctx.getBean(BookDao.class);
bookDao.save();
}
}
下面是创建好后的结构目录:
我们所需要的基础环境搭建好了,现在我们就开始实现AOP
吧!
AOP实现步骤
步骤一:在pom.xml中添加所需要的依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
我们所需要的spring-aop
依赖在前面的spring-context
中已经包含了,我们只需要导入AspectJ
就可以。AspectJ
是AOP思想的一个具体实现,Spring有自己的AOP实现,但是相比于AspectJ来说比较麻烦,所以我们直接采用Spring整合ApsectJ的方式进行AOP开发。
步骤二:定义接口与实现类
我们在环境准备时已经做好了,不用做任何修改
步骤三:定义通知类和通知
通知就是将共性功能抽取出来后形成的方法,共性功能指的就是当前系统时间的打印。
public class MyAdvice {
public void method(){
System.out.println(System.currentTimeMillis());
}
}
步骤四:定义切入点
我们在前面定义的BookDaoImpl中有两个方法,分别是save和update,我们要增强的是update方法,该如何定义呢?
public class MyAdvice {
@Pointcut("execution(void com.hzy.dao.BookDao.update())")
private void pt(){
}
public void method(){
System.out.println(System.currentTimeMillis());
}
}
注意:
- 切入点定义依托一个不具有实际意义的方法进行,即无参数、无返回值、方法体无实际逻辑。
execution
及后面编写的内容,后面我会给大家讲到。
步骤五:制作切面
还是在MyAdvice类中:
public class MyAdvice {
@Pointcut("execution(void com.hzy.dao.BookDao.update())")
private void pt(){
}
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis())