Spring AOP 切面应用

379 阅读2分钟

「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」。

概念

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只

支持方法类型的连接点.

Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义,也可以说是连接点的集合

Advice(通知/增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知.通知分为前置通知,后置

通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Target(目标对象):代理的目标对象

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.

spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载器织入

Proxy(代理):一个类被 AOP 织入增强后,就产生一个结果代理类

Aspect(切面): 是切入点和连接点,通知(引介)的结合

通知类型:

前置通知 :在目标方法执行之前执行.

后置通知 :在目标方法执行之后执行

环绕通知 :在目标方法执行前和执行后执行

异常抛出通知:在目标方法执行出现 异常的时候 执行

最终通知 :无论目标方法是否出现异常 最终通知都会 执行.

AOP XML配置方式


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">

<!-- 指定扫描cn.itcast.bean报下的所有类中的注解.

     注意:扫描包时.会扫描指定报下的所有子孙包

 -->

<context:component-scan base-package="li.entity"></context:component-scan>

<!--配置目标对象  -->

<bean name="UserDao" class="li.aspact.UserServiceImpl"></bean>

<!-- 配置通知类 -->

<bean name="MyAdvice" class="li.aspact.MyAdvice"></bean>

<!--配置将通知织入目标对象  -->

<aop:config>

<!-- 配置切入点

expression:li.aspact.UserServiceImpl.add():指定具体的切入点

*li.aspact.UserServiceImpl.*():指定该类不带参数所有的方法

*li.aspact.UserServiceImpl.*(..):指定该类无论带参还是不带参所有方法

*li.aspact.*ServiceImpl.*(..):指定aspect包下所有以ServiceImpl结尾的类中所有的方法

-->

<aop:pointcut expression="execution(*li.aspact.UserServiceImpl.add())" id="pc"/>

<aop:aspect ref="MyAdvice">

<!--  before方法设为前置通知-->

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

<aop:after-returning method="afterReturning" pointcut-ref="pc"/>

<aop:after-throwing method="afterException" pointcut-ref="pc"/>

<aop:around method="around" pointcut-ref="pc"/>

<aop:after method="after" pointcut-ref="pc" />

</aop:aspect>

</aop:config>

</beans>

AOP 注解方式


@Component

@Aspect

public class AopConfig {

@Pointcut("execution(* com.spring.aop.*.*(..))")

public void pointCut() {

}

@Before("pointCut()")

public void before(){

System.out.println("before...");

}

@After("pointCut()")

public void after(){

System.out.println("after....");

}

@Around("pointCut()")

public void arround(ProceedingJoinPoint point){

System.out.println("arround-=-=-=-=-=-=before");

try {

point.proceed();

} catch (Throwable throwable) {

throwable.printStackTrace();

}

System.out.println("arround-=-=-=-=-=-=after");

}

}

静态代理和动态代理

概念

代理的作用就是增强对象的功能

代理对象可以理解成被增强的对象

目标对象就是被增强的对象

静态代理

继承

代理对象继承目标对象,重写需要增强的方法

缺点:代理对象会随着业务需求的不断扩大而变多,难以管理

聚合

目标对象和代理对象实现同一接口,代理对象,代理对象要包含目标对象

缺点:同样会产生许多代理对象