spring-aop基本概念
程序员文章站
2022-07-13 17:43:49
...
AOP词汇:
Joinpoint:在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。通俗的说就是加入切点的那个点.ProceedingJoinPoint
Advice:待织入的逻辑
前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
继承结构:
使用方法:
Advisor:拥有Advice的接口
PointcutAdvisor:拥有切点逻辑Advisor
DefaultPointcutAdvisor:默认拥有匹配所有类和方法的pointcut 和 Advice 的实现
其他:
RegexpMethodPointcutAdvisor:需要加上完整的类名和方法名,例如:com.xw.methodname或com.*.methodname或.*methodname
NameMatchMethodPointcutAdvisor:只需要方法名,不用加类名:*methodname
切入点:
Pointcut:提供类层面(ClassFilter)和方法层面(MethodMatcher)的匹配逻辑
AOP代理:
Cglib2AopProxy:基于cglib实现的代理,核心:Enhancer
JdkDynamicAopProxy:基于jdk动态代理实现,核心接口:InvocationHandler
切面:
Aspect:是一个Pointcut 和 多个Advice的模块化逻辑单元
最后总结:
举例:
1、Spring AOP:自动代理(扫描切面配置)
这里无需再配置代理了,因为代理将会由 DefaultAdvisorAutoProxyCreator 自动生成。也就是说,这个类可以扫描所有的切面类,并为其自动生成代理。
2、Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)
类上面标注的 @Aspect 注解,这表明该类是一个 Aspect(其实就是 Advisor)。该类无需实现任何的接口,只需定义一个方法(方法叫什么名字都无所谓),只需在方法上标注 @Around 注解,在注解中使用了 AspectJ 切点表达式。方法的参数中包括一个 ProceedingJoinPoint 对象,它在 AOP 中称为 Joinpoint(连接点),可以通过该对象获取方法的任何信息,例如:方法名、参数等。
3、Spring + AspectJ(基于配置)
使用 <aop:config> 元素来进行 AOP 配置,在其子元素中配置切面,包括增强类型、目标方法、切点等信息。
无论您是不能使用注解,还是不愿意使用注解,Spring AOP 都能为您提供全方位的服务。
Joinpoint:在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。通俗的说就是加入切点的那个点.ProceedingJoinPoint
Advice:待织入的逻辑
前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
继承结构:
使用方法:
Advisor:拥有Advice的接口
PointcutAdvisor:拥有切点逻辑Advisor
DefaultPointcutAdvisor:默认拥有匹配所有类和方法的pointcut 和 Advice 的实现
其他:
RegexpMethodPointcutAdvisor:需要加上完整的类名和方法名,例如:com.xw.methodname或com.*.methodname或.*methodname
NameMatchMethodPointcutAdvisor:只需要方法名,不用加类名:*methodname
切入点:
Pointcut:提供类层面(ClassFilter)和方法层面(MethodMatcher)的匹配逻辑
AOP代理:
Cglib2AopProxy:基于cglib实现的代理,核心:Enhancer
JdkDynamicAopProxy:基于jdk动态代理实现,核心接口:InvocationHandler
切面:
Aspect:是一个Pointcut 和 多个Advice的模块化逻辑单元
最后总结:
举例:
1、Spring AOP:自动代理(扫描切面配置)
<?xml version="1.0" encoding="UTF-8"?> <beans ...> ... <bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="pattern" value="aop.demo.GreetingImpl.good.*"/> <property name="advice" ref="greetingAroundAdvice"/> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> <property name="optimize" value="true"/> </bean> </beans>
这里无需再配置代理了,因为代理将会由 DefaultAdvisorAutoProxyCreator 自动生成。也就是说,这个类可以扫描所有的切面类,并为其自动生成代理。
2、Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)
@Aspect @Component public class GreetingAspect { @Around("execution(* aop.demo.GreetingImpl.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { before(); Object result = pjp.proceed(); after(); return result; } private void before() { System.out.println("Before"); } private void after() { System.out.println("After"); } }
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="aop.demo"/> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>
类上面标注的 @Aspect 注解,这表明该类是一个 Aspect(其实就是 Advisor)。该类无需实现任何的接口,只需定义一个方法(方法叫什么名字都无所谓),只需在方法上标注 @Around 注解,在注解中使用了 AspectJ 切点表达式。方法的参数中包括一个 ProceedingJoinPoint 对象,它在 AOP 中称为 Joinpoint(连接点),可以通过该对象获取方法的任何信息,例如:方法名、参数等。
3、Spring + AspectJ(基于配置)
<?xml version="1.0" encoding="UTF-8"?> <beans ..."> <bean id="greetingImpl" class="aop.demo.GreetingImpl"/> <bean id="greetingAspect" class="aop.demo.GreetingAspect"/> <aop:config> <aop:aspect ref="greetingAspect"> <aop:around method="around" pointcut="execution(* aop.demo.GreetingImpl.*(..))"/> </aop:aspect> </aop:config> </beans>
使用 <aop:config> 元素来进行 AOP 配置,在其子元素中配置切面,包括增强类型、目标方法、切点等信息。
无论您是不能使用注解,还是不愿意使用注解,Spring AOP 都能为您提供全方位的服务。
上一篇: flask项目拆分重构实例