springAOP

image-20210712164634609

Aop在Spring中的作用

提供声明式事务;允许用户自定义切面

  • 横切关注点:跨域应用程序多个模块的方法或功能。既是,与业务逻辑无关的,但需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等
  • 切面(aspect):横切关注点 被模块化的特殊对象。既,它是一个类。(Log)
  • 通知(adivce):切面必须要完成的工作。既,它是类中的一个方法。(Log的方法)
  • 目标(target):被通知对象。(接口或者方法)
  • 代理(Proxy):向目标对象应用通知之后创建的对象。(生成的代理类)
  • 切入点(PointCut):切面通知 执行的“地点”的定义。
  • 连接点(JointPoint):与切入点匹配的执行点。

image-20210712212938982

在SpringAop中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

image-20210712213529243

intercept:拦截

alliance:联盟

使用Spring实现AOP

导入依赖包:

1
2
3
4
5
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>

方式一:使用SPring的API接口

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--    先要注册bean-->
<bean id="userService" class="com.lrr.service.UserServiceImpl"/>
<bean id="log" class="com.lrr.log.Log"/>
<!-- 方式一:使用元素Spring API接口-->
<!-- 配置aop:需要导入aop的约束-->
<aop:config>
<!--切入点:expression:表达式,execution(要执行的位置 修饰词 返回值 类名 方法名 参数),用空格分隔-->
<!-- 两个点代表任意参数-->
<aop:pointcut id="pointcut" expression="execution(* com.lrr.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加-->
<!-- 将log这个类切入到pointcut中需要增加的方法-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
</aop:config>

方式二:自定义来实现AOP

1
2
3
4
5
6
7
8
9
10
11
12
<!--    方式二-->
<bean id="diy" class="com.lrr.DIY.DiyPointCut"/>
<aop:config>
<!-- 切面,ref要引用的类-->
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="point" expression="execution(* com.lrr.service.UserServiceImpl.*(..))"/>
<!-- 通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>

方式三:使用注解实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@Aspect // 标注这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.lrr.service.UserServiceImpl.*(..))") // 需要加入切入点
public void before(){
System.out.println("方法执行前 --------------------->");
}


@After("execution(* com.lrr.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("方法执行后 --------------------->");
}

// 在环绕增强中,可以给定参数,代表我们要获取处理切入的点
@Around("execution(* com.lrr.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前 ---------------->");


System.out.println(jp.getSignature());
// 执行方法
Object proceed = jp.proceed();

System.out.println("环绕后");
}
}
1
2
3
4
5
<!--    方式三-->
<!-- 在这个类上面加Component也可以-->
<bean id="annotationPointCut" class="com.lrr.DIY.AnnotationPointCut"/>
<!-- 开启注解支持!-->
<aop:aspectj-autoproxy/>

execution表达式

execution(* com.sample.service.impl..*.*(..))

解释如下:

符号 含义
execution() 表达式的主体
第一个 * 表示返回值的任意类型
com.sample.servie.impl AOP所切的服务的包名,既,业务部分
包名后面的.. 表示当前包和子包
第二个 * 表示类名,* 既所有类。此处可自定义
.*(..) 表示任何方法名,括号表示参数,两个表示任何参数类型

参考:(46条消息) 深入浅出-Spring execution表达式_任我行哟的博客-CSDN博客_execution表达式

作者

bd160jbgm

发布于

2021-07-12

更新于

2021-07-13

许可协议