spring-aop基本概念

本文深入解析Spring AOP的核心概念,包括Joinpoint、Advice、Pointcut等,并通过实例演示如何使用Spring AOP及AspectJ实现方法拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP词汇:

[b]Joinpoint[/b]:在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。通俗的说就是加入切点的那个点.ProceedingJoinPoint

[b]Advice[/b]:待织入的逻辑
前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。

继承结构:
[img]http://dl2.iteye.com/upload/attachment/0119/5039/166d5056-1164-3d27-8736-f729f855dd9e.png[/img]

使用方法:

[img]http://dl2.iteye.com/upload/attachment/0119/5041/821f9473-7559-3b9f-b525-76b8db195c59.jpg[/img]


[b]Advisor[/b]:拥有Advice的接口
[b]PointcutAdvisor[/b]:拥有切点逻辑Advisor
[b]DefaultPointcutAdvisor[/b]:默认拥有匹配所有类和方法的pointcut 和 Advice 的实现
其他:
[b]RegexpMethodPointcutAdvisor[/b]:需要加上完整的类名和方法名,例如:com.xw.methodname或com.*.methodname或.*methodname
[b]NameMatchMethodPointcutAdvisor[/b]:只需要方法名,不用加类名:*methodname

切入点:
[b]Pointcut[/b]:提供类层面(ClassFilter)和方法层面(MethodMatcher)的匹配逻辑

AOP代理:
[b]Cglib2AopProxy[/b]:基于cglib实现的代理,核心:Enhancer
[b]JdkDynamicAopProxy[/b]:基于jdk动态代理实现,核心接口:InvocationHandler

切面:
[b]Aspect[/b]:是一个Pointcut 和 多个Advice的模块化逻辑单元


最后总结:

[img]http://dl2.iteye.com/upload/attachment/0119/5043/40294d07-613a-3dc0-952b-3fd1a6ae0467.png[/img]


举例:
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 都能为您提供全方位的服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值