栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

第12章-Spring基于注解配置AOP

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第12章-Spring基于注解配置AOP

文章目录
    • 一、概述
    • 二、AOP 使用
      • 1. 定义切面
      • 2. 定义切点
      • 3. 定义通知
      • 4. 通过 Advisor 实现
    • 三、附录
      • 1. 常用配置
      • 2. 常用注解
      • 3. 示例代码

Spring 的 AOP 功能是基于 AspectJ 实现的,支持使用注解声明式定义 AOP 切面。

理解 AOP 概念参阅:《Spring的AOP和动态代理》

一、概述

Spring 项目使用 AOP 功能需要定义三个部分:切面、切点和通知。

二、AOP 使用

Spring 基于注解配置 AOP 需要启用 AspectJ 自动代理功能。

基于 Java 配置

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

基于 XML 配置


1. 定义切面

在 Spring 管理的 Bean 类上使用 @Aspect 注解就可以定义一个切面。

@Aspect
@Component
public class DemoAspect {

}
2. 定义切点

在切面类的方法使用 @Pointcut 注解来定义切点,然后在通知注解中使用方法签名来指定切点。

切点表达式用来匹配切入的目标类和方法。目标类只能是 Spring 容器管理的类,切面只能切入 Bean 中的方法。

@Aspect
@Component
public class DemoAspect {

    @Pointcut("execution(* cn.codeartist.spring.aop.aspectj.*.*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint) {
		// do something
    }
}

切点表达式也可以在定义通知的时候指定,而不需要使用 @Pointcut 注解。

@Aspect
@Component
public class DemoAspect {

    @Before("execution(* cn.codeartist.spring.aop.aspectj.*.*(..))")
    public void doBefore(JoinPoint joinPoint) {
		// do something
    }
}
3. 定义通知

定义通知的时候需要指定切点,通知的类型决定了切入的节点。

前置通知

使用 @Before 注解定义前置通知,在方法执行前添加操作。

@Aspect
@Component
public class DemoAspect {

    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint) {
		// do something
    }
}

后置通知

使用 @AfterReturning 注解定义后置通知,在方法正常返回时执行,方法抛异常不执行。

@Aspect
@Component
public class DemoAspect {

    @AfterReturning("pointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {
		// do something
    }
}

环绕通知

使用 @Around 注解定义环绕通知,切入方法前后,相当于拦截器的功能,可以捕获异常处理。

环绕通知的切入点参数为 ProceedingJoinPoint,并且需要手动调用 proceed() 来执行切入点方法的逻辑。

@Aspect
@Component
public class DemoAspect {

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
		// do something
        Object proceed = joinPoint.proceed();
		// do something
        return proceed;
    }
}

最终通知

使用 @After 注解定义最终通知,在方法退出时执行,无论是正常退出还是异常退出。

@Aspect
@Component
public class DemoAspect {

    @After("pointcut()")
    public void doAfter(JoinPoint joinPoint) {
		// do something
    }
}

异常通知

使用 @AfterThrowing 注解定义异常通知,在方法抛出异常时执行。

@Aspect
@Component
public class DemoAspect {

    @AfterThrowing("pointcut()")
    public void doAfterThrowing(JoinPoint joinPoint) {
		// do something
    }
}
4. 通过 Advisor 实现

使用 Advisor 能以编程的方式创建切面,需要实现通知的 API 来定义通知的类型。

比起使用注解定义切点,这种方式指定切点表达式更灵活。

@Bean
public AspectJexpressionPointcutAdvisor aspectJexpressionPointcutAdvisor() {
    AspectJexpressionPointcutAdvisor advisor = new AspectJexpressionPointcutAdvisor();
    advisor.setexpression("execution(* cn.codeartist.spring.aop.aspectj.*.*(..))");
    advisor.setAdvice((MethodBeforeAdvice) (method, args, target) -> {
        // do something
    });
    return advisor;
}
三、附录 1. 常用配置
配置描述
启用 AspectJ 自动代理,通过注解定义切面
2. 常用注解
注解描述
@EnableAspectJAutoProxy启用 AspectJ 自动代理,通过注解定义切面
@Aspect定义切面类
@Pointcut定义切点,指定切点表达式
@Before定义前置通知
@AfterReturning定义后置通知
@Around定义环绕通知
@After定义最终通知
@AfterThrowing定义异常通知
3. 示例代码

Gitee 仓库:https://gitee.com/code_artist/spring
项目模块:spring-aop
示例路径:cn.codeartist.spring.aop.aspectj

最新文章关注 CodeArtist 码匠公众号。

更多:Spring高效实践专栏

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682443.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号