SpringBoot 自定义注解

本文详细介绍了如何在SpringBoot项目中创建并使用自定义注解,结合AOP实现切面编程。从创建项目到添加依赖,再到定义注解、切面类,最后通过实际例子展示了注解的使用和测试,包括前置通知、环绕通知、后置通知等。同时,文中提供了相关注解和方法的参考资料链接。
摘要由CSDN通过智能技术生成

新建SpringBoot 项目

选择Spring Initializr 点击Next

写好名字,Java version选择8,点击Next

选择Web,点击Next

写好名字,点击Finish,项目创建完成。

 添加aop依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
   	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

自定义注解

创建annotation文件夹(名字随意),然后新建一个注解类 MyAnnotation ,注意这是一个@interface,在 Kind 处选择Annotation

interface :声明了这是一个java 的接口

@interface : 用来修饰 Annotation,请注意,它不是 interface。这个关键字声明隐含了一个信息:它继承了 java.lang.annotation.Annotation 接口,而不是声明了一个 interface。

代码如下: 

package com.example.demo.annotation;

import java.lang.annotation.*;


@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {

    String value();
}

关于@Target @Retention @Documented 这几个注解可以参考一下这个文件:

https://blog.csdn.net/liang100k/article/details/79515910

@Component 注解参考文章:https://www.cnblogs.com/Tenfei/articles/14145261.html

@Pointcut 可以参考一下这个文章:https://blog.csdn.net/elim168/article/details/78150438

然后创建切面类,注意:要选择@Aspct,或者直接创建一个class类,然后在类上方添加@Aspect注解。





代码如下:

package com.example.demo.annotation;

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

import java.util.Arrays;

@Aspect
@Component
public class MyAspect {
    /*
     * 切入点-- @Pointcut --》定义需要切面的地方,表达式参数
     * 匹配top.alanlee.template.controller包及其子包下的所有类的所有方法
     * 切入点方法不用写代码,返回类型为void
     * execution:用于匹配表达式 将符合条件下的方法和合适的参数作为切面引入
     */
    //匹配所有com.example.demo.annotation包下所有类的所有方法
    //@Pointcut("execution(* com.example.demo.annotation.*.*(..))")
    @Pointcut("@annotation(com.example.demo.annotation.MyAnnotation)")
    public void myPointCut(){

    }

    /*
    * 前置通知,目标方法调用前被调用
    * */
    @Before("myPointCut()")
    public void beforePointcut(JoinPoint joinPoint){
        System.out.println("前置通知开始。。。");
        Signature signature = joinPoint.getSignature();
        System.out.println("目标方法的签名:" + signature);
        System.out.println("代理方法的名字:" + signature.getName());
        Object[] args = joinPoint.getArgs();
        System.out.println("获取目标方法的参数信息:" + Arrays.asList(args));
        System.out.println("前置通知结束。。。");
    }

    /**
     * 环绕通知
     * 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
     * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
     * @param proceedingJoinPoint
    **/
    @Around("myPointCut()")
    public void arroundPointcut(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知开始。。。");
        String name = proceedingJoinPoint.getSignature().getName();
        System.out.println("环绕通知的目标方法名:" + name);
        proceedingJoinPoint.proceed();//执行到这里开始走进来的方法体(必须声明)
        System.out.println("环绕通知结束。。。");
    }

    /*
    最终通知,目标方法执行完之后执行
     */
    @After("myPointCut()")
    public void afterPointcut(){
        System.out.println("后置通知。。。");
    }

    /*
     * 后置返回通知
     * 如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息
     * 如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
     * returning 只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行
     * @param joinPoint
     * @param keys
    * */
    // @AfterReturning(value = "execution(* com.haijiao12138.demo.spring.aop0813.AopController1..*.*(..))", returning = "keys")
    @AfterReturning("myPointCut()")
    public void afterReturn(JoinPoint joinPoint){
        System.out.println("后置返回通知。。。");

    }

    /** 后置异常通知
     * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法;
     * throwing 只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行,
     */
     @AfterThrowing(value = "myPointCut()", throwing = "e")
//    @AfterThrowing("myPointCut()")
    public void afterThrow(JoinPoint joinPoint, NullPointerException e){
         System.out.println("后置异常通知。。。");
    }

}

上面基本上完成了自定义注解的开发,在使用中可以直接使用 @MyAnnotation("") 即可。

这里在方法上加了 @MyAnnotation("") 注解(后面括号不可以省略),如果在定义注解类时,即在 MyAnnotation类里设置默认值就可以只写 @MyAnnotation (因为有默认值,所以可以省略括号里的双引号)。当然,需要设置后面括号里的内容时不可以省略。

public @interface MyAnnotation {
    String value() default "";
}

代码如下:

package com.example.demo.annotation;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/myAnnotation")
public class TestController {

    @MyAnnotation("")
    @RequestMapping("/test")
    public String test(String key){
        System.out.println("test--myAnnotation:" + key);
        return "test--myAnnotation:" + key;
    }

    @MyAnnotation("")
    @RequestMapping("testAfterThrowing")
    public String testAfterThrowing(String key){
        System.out.println(key);
        throw new NullPointerException(key);
    }

    @MyAnnotation("")
    @RequestMapping("/testAround")
    public String testAround(String key){
        System.out.println("环绕通知:key = " + key);
        return "环绕通知:key = " + key;
    }

}

测试

1-测试test,访问:http://localhost:8080/myAnnotation/test?key=hello

 2-测试testAfterThrowing,访问:http://localhost:8080/myAnnotation/testAfterThrowing?key=erroe

 

3-测试环绕通知testAround,访问:http://localhost:8080/myAnnotation/testAround?key=arround 

SpringBoot中可以自定义注解来实现特定的功能。自定义注解的步骤如下: 1. 使用`@interface`关键字来定义注解,可以在注解中设置属性。 2. 可以通过注解的属性来传递参数,比如设置注解中的属性值。 3. 可以通过判断某个类是否有特定注解来进行相应的操作。 在SpringBoot中,自定义注解可以用于实现日志记录、定时器等功能。通过使用注解,可以简化代码,并提高开发效率。同时,自定义注解也是Spring框架中广泛应用的一种方式,可以在SpringMVC框架中使用注解来配置各种功能。而在SpringBoot框架中,更是将注解的使用推向了极致,几乎将传统的XML配置都替换为了注解。因此,对于SpringBoot来说,自定义注解是非常重要的一部分。123 #### 引用[.reference_title] - *1* *3* [springboot 自定义注解(含源码)](https://blog.csdn.net/yb546822612/article/details/88116654)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *2* [SpringBoot-自定义注解](https://blog.csdn.net/weixin_44809337/article/details/124366325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值