一. Spring AOP定义:
(Aspect Oriented Programming)面向切面编程:在软件运行过程中,执行前后都可以额外增加相应扩展功能,我们把这个功能称为切面。切面可以轻松进行安装和移除。我们可以形象把切面理解成浏览器的插件,需要就安装,不需要就卸载。
- AOP的做法是将通用,与业务无关的功能抽象封装为切面类
- 最终目的:在不锈钢源码的情况下对程序行为进行扩展
-
为什么要把扩展功能被称为切面?
答:正常软件业务流程是从上到下依次执行的,我们加的功能就像横切面一样穿加在原始软件的运行过程中
在这里插入图片描述
二,AOP相关概念
一,spring aop与AspectJ的关系:
-
Eclipse AspectJ,一种基于java平台的面向切面编程的语言,有一套完整体系,可以运行时实现aop面向切面编程的理念
-
但是spring aop并不是完全使用AspectJ来实现的,只是在底层依赖AspectJWeaver实现类与方法匹配
如截图,这个范围圈定的过程就是依赖AspectJWeaver来实现
这个范围圈定的过程就是依赖AspectJWeaver来实现
- Spring AOP核心原理是利用代理模式实现对象运行时功能扩展
二,关键概念
注解 | 说明 |
---|---|
Aspect | 切面,具体的可插拔组件功能类,通常一个切面只实现一个通用功能。本质是一个标准的类,无需继承和实现其他类。格式必须为public,返回值可以是void或者object |
Target Class/Method | 目标类/目标方法,指真正要执行与业务相关的方法。功能类似于service,dao里面的insert,create方法 |
PointCut | 切入点:使用execution表达式说明切面要作用在系统的哪些类上 |
JoinPoint | 连接点,切面运行过程中是包含了目标类/方法元数据的对象。必须在切面方法里传入这个。元数据:描述目标类和目标方法的信息 |
Advice | 通知,说明具体的切面的执行时机,spring包含了五种不同类型通知。 |
三,AOP配置过程:
- 依赖AspectJ
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!--spring aop的底层依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
</dependencies>
- 实现切面类,方法
// 切面类
public class MethodAspect {
// 切面方法,用于扩展额外功能
public void printExecutionTime(JoinPoint joinpoint) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss SSS");
String now = sdf.format(new Date());
String className = joinpoint.getTarget().getClass().getName();//获取目标类名
String methodName = joinpoint.getSignature().getName();// 获取目标方法名
System.out.println("---->" + now + ":" + className + "." + methodName);
}
}
-
配置切面类Aspect Bean
-
定义PointCut(当前切面作用于系统的哪些类的哪些方法)
-
配置Advice通知
配置文件完整版如下:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userDao" class="com.imooc.spring.aop.dao.UserDao"/>
<bean id="userService" class="com.imooc.spring.aop.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="employeeDao" class="com.imooc.spring.aop.dao.EmployeeDao"/>
<bean id="employeeService" class="com.imooc.spring.aop.service.EmployeeService">
<property name="employeeDao" ref="employeeDao"/>
</bean>
<!--2,aop配置:配置切面类Aspect Bean-->
<bean id="methodAspect" class="com.imooc.spring.aop.aspect.MethodAspect">
</bean>
<aop:config>
<!--3,定义PointCut-->
<!--pointcut:切点,使用expression表达式说明作用范围-->
<!--execution(public * com.imooc..*.*(..))说明切面的作用com.imooc包下所有类的所有方法-->
<aop:pointcut id="pointcut" expression="execution(public * com.imooc..*.*(..))"/>
<!--4,定义切面类-->
<aop:aspect ref="methodAspect">
<!--5,配置Advice通知:before通知,代表在目标方法运行前运行methodAspect.printExecutionTime方法-->
<aop:before method="printExecutionTime" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
四,JoinPoint对象
JoinPoint:获取目标类和目标方法的核心信息
核心方法具体代码演示
代码演示
实际工作中线上项目如要进行跟踪调试,可以增加这个切面,使用logback日志对参数进行输出
五,PointCut切点表达式
- public可省略
- 返回值可以匹配任意的(*),也可以为void或者是String,object对象之类的
- 类名比如我要匹配包含service的,可以写成*service,其他的同理
-
举个栗子
示例
网友评论