ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

spring——基于注解的AspectJ AOP开发(转载)

2022-04-23 13:32:57  阅读:161  来源: 互联网

标签:定义 spring 通知 AOP 注解 net biancheng AspectJ


在 Spring 中,虽然我们可以使用 XML 配置文件可以实现 AOP 开发,但如果所有的配置都集中在 XML 配置文件中,就势必会造成 XML 配置文件过于臃肿,从而给维护和升级带来一定困难。

为此,AspectJ 框架为 AOP 开发提供了一套 @AspectJ 注解。它允许我们直接在 Java 类中通过注解的方式对切面(Aspect)、切入点(Pointcut)和增强(Advice)进行定义,Spring 框架可以根据这些注解生成 AOP 代理。

关于注解的介绍如表 1 所示。

表 1 Annotation 注解介绍
名称说明
@Aspect 用于定义一个切面。
@Pointcut 用于定义一个切入点。
@Before 用于定义前置通知,相当于 BeforeAdvice。
@AfterReturning 用于定义后置通知,相当于 AfterReturningAdvice。
@Around 用于定义环绕通知,相当于 MethodInterceptor。
@AfterThrowing 用于定义抛出通知,相当于 ThrowAdvice。
@After 用于定义最终通知,不管是否异常,该通知都会执行。
@DeclareParents 用于定义引介通知,相当于 IntroductionInterceptor(不要求掌握)。

启用 @AspectJ 注解支持

在使用 @AspectJ 注解进行 AOP 开发前,首先我们要先启用 @AspectJ 注解支持。

我们可以通过以下 2 种方式来启用 @AspectJ 注解。

1)使用 Java 配置类启用

我们可以在 Java 配置类(标注了 @Configuration 注解的类)中,使用 @EnableAspectJAutoProxy 和 @ComponentScan 注解启用 @AspectJ 注解支持。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

定义通知 

AspectJ 为我们提供了以下 6 个注解,来定义 6 种不同类型的通知(Advice),如下表。

 
注解说明
@Before 用于定义前置通知,相当于 BeforeAdvice。
@AfterReturning 用于定义后置通知,相当于 AfterReturningAdvice。
@Around 用于定义环绕通知,相当于 MethodInterceptor。
@AfterThrowing 用于定义抛出通知,相当于 ThrowAdvice。
@After 用于定义最终通知,不管是否异常,该通知都会执行。
@DeclareParents 用于定义引介通知,相当于 IntroductionInterceptor(不要求掌握)。


以上这些通知注解中都有一个 value 属性,这个 value 属性的取值就是这些通知(Advice)作用的切点(PointCut),它既可以是切入点表达式,也可以是切入点的引用(切入点对应的方法名称),示例代码如下。

 

 

 

 

 

 

 

 

 

 

示例

下面,我们就通过一个完整的实例,来演示下如何通过注解的方式实现 AspectJ AOP 开发。

1. 新建一个名为 my-spring-asepctj-demo2 的 Java 项目,并将以下依赖 Jar 包导入到该项目中。

  • commons-logging-1.2.jar
  • spring-aop-5.3.13.jar
  • spring-aspects-5.3.13.jar
  • spring-beans-5.3.13.jar
  • spring-context-5.3.13.jar
  • spring-core-5.3.13.jar
  • spring-expression-5.3.13.jar
  • aspectjweaver-1.9.7.jar


2. 在 net.biancheng.c.dao 包下,创建一个名为 UserDao 的接口,代码如下。

 

 

 

 

 

 

 

 

 

 


5. 在 net.biancheng.c 包下,创建一个名为 MyAspect 的切面类,代码如下。

package net.biancheng.c;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component // 定义成 Bean
@Aspect //定义为切面
public class MyAspect {
    @Before("execution(* net.biancheng.c.dao.UserDao.add(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置增强……" + joinPoint);
    }

    @After("execution(* net.biancheng.c.dao.UserDao.get(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("最终增强……" + joinPoint);
    }


    /**
     * 将 net.biancheng.c.dao包下的 UserDao 类中的 get() 方法 定义为一个切点
     */
    @Pointcut(value = "execution(* net.biancheng.c.dao.UserDao.get(..))")
    public void pointCut1() {

    }

    /**
     * 将 net.biancheng.c.dao包下的 UserDao 类中的 delete() 方法 定义为一个切点
     */
    @Pointcut(value = "execution(* net.biancheng.c.dao.UserDao.delete(..))")
    public void pointCut2() {

    }

    //使用切入点引用
    @Around("MyAspect.pointCut2()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕增强……1");
        proceedingJoinPoint.proceed();
        System.out.println("环绕增强……2");
    }

    //使用切入点表达式
    @AfterReturning(value = "execution(* net.biancheng.c.dao.UserDao.modify(..))", returning = "returnValue")
    public void afterReturning(Object returnValue) {
        System.out.println("后置返回增强……,方法返回值为:" + returnValue);
    }
}

  

 

 

 

 

 

 

 

 

 

 

 

标签:定义,spring,通知,AOP,注解,net,biancheng,AspectJ
来源: https://www.cnblogs.com/xiaobaibailongma/p/16182191.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有