目录
Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的一个关键组件,它允许开发者通过定义切面(aspects)来实现横切关注点(cross-cutting concerns),比如日志、事务管理、安全等,而不用修改主业务逻辑的代码。
1. 核心概念
AOP术语
- Aspect(切面): 封装了横切关注点的模块,通常是一个类。
- Join Point(连接点): 程序执行的某个特定位置,如方法调用或异常处理。
- Advice(通知): 切面在特定连接点上执行的动作。
- Pointcut(切入点): 匹配连接点的表达式,用来确定是否应用通知。
- Target Object(目标对象): 被一个或多个切面所通知的对象。
- Proxy(代理): AOP框架创建的对象,用来实现切面契约。
- Weaving(织入): 将切面与其他应用程序类型或对象连接起来,创建一个被通知的对象。
通知类型
- Before advice(前置通知): 方法执行前执行的通知。
- After returning advice(后置通知): 方法正常执行后执行的通知。
- After throwing advice(异常通知): 方法抛出异常后执行的通知。
- After advice(最终通知): 方法执行后无论是否抛出异常都执行的通知。
- Around advice(环绕通知): 包围一个方法的通知,可以在方法调用前后自定义行为。
2. 实现AOP的方式
Spring AOP可以通过两种方式实现:
基于代理的AOP
- Spring AOP: 使用Java动态代理或CGLIB代理,适用于方法级别的拦截。
- ProxyFactoryBean: Spring提供的用于生成AOP代理的工厂Bean。
基于AspectJ的AOP
- @AspectJ support: Spring支持使用AspectJ注解方式定义切面。
3. 定义切面
使用@Aspect
注解定义一个切面,并通过@Pointcut
声明切入点,使用@Before
、@AfterReturning
、@AfterThrowing
、@After
和@Around
注解声明通知。
@Aspect
public class LoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
private void selectAll(){}
@Before("selectAll()")
public void beforeAdvice(){
// 前置通知内容
}
@AfterReturning(pointcut = "selectAll()", returning="retVal")
public void afterReturningAdvice(Object retVal){
// 后置通知内容
}
// 其他通知...
}
4. 配置AOP
在Spring配置文件中或使用Java配置,注册切面并启用AOP自动代理。
XML配置
<aop:config>
<aop:aspect id="myAspect" ref="aLoggingAspect">
<aop:pointcut id="selectAll" expression="execution(* com.example.service.*.*(..))"/>
<aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
<!-- 其他通知配置 -->
</aop:aspect>
</aop:config>
Java配置
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
@Bean
public LoggingAspect loggingAspect() {
return new LoggingAspect();
}
}
或者直接在切面类使用@Service注解也可以
5. 使用AOP
一旦配置好AOP,Spring容器将为那些与切入点表达式匹配的Bean创建代理。当调用代理对象的方法时,相应的通知将被触发。
注意事项
- Spring AOP默认使用标准的Java动态代理作为AOP代理,这意味着它只能代理接口。如果需要代理类而不是接口,需要使用CGLIB库。
- Spring AOP主要用于拦截方法调用。对于字段拦截或构造函数拦截,需要使用AspectJ。
- 确保切面的执行顺序(如果有多个切面)是正确的,可以使用
@Order
或实现Ordered
接口来定义。 - AOP可能会增加系统的复杂性,应当谨慎使用,以免过度使用影响代码的可读性和维护性。