「这是我参与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");
}
}
静态代理和动态代理
概念
代理的作用就是增强对象的功能
代理对象可以理解成被增强的对象
目标对象就是被增强的对象
静态代理
继承
代理对象继承目标对象,重写需要增强的方法
缺点:代理对象会随着业务需求的不断扩大而变多,难以管理
聚合
目标对象和代理对象实现同一接口,代理对象,代理对象要包含目标对象
缺点:同样会产生许多代理对象