SpringBoot的自定义注解

前言:在整个Spring框架中提供了许多的注解,今天就来讲讲如何自定义注解

自定义注解内容讲解

@Target  (表示该注解可以使用的范围)

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中

@Retention({RetentionPolicy.Runtime}) 注解    指定注解需要保存多长时间

        Runtime  指的是运行期级别

        Class      指的是编译期级别

        Source    指的是源码级别

@Documented注解

Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。

关于@Target  @Document等具体详细讲解,可以参考:https://blog.csdn.net/liang100k/article/details/79515910

我在学习这部分内容的时候看到一个概念,元注解。

元注解即注解的注解,包括@Retention @Target @Document @Inherited四种。

详细内容可以参考:https://www.cnblogs.com/zhi-xing/p/10842978.html

 

实战部分

在pom引用aop的jar包

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

(1) 定义一个自定义注解的类

package com.test.common;

/**
 * @Author tanghh
 * @Date 2020/1/16 15:49
 */

import java.lang.annotation.*;

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

    String module() default "";

    String[] params() default {};

    boolean isDetail() default true;

}

(2)Spring Aop的操作类

package com.test.aspect;

import com.test.common.NewsRecord;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @Author tanghh
 * @Date 2020/1/16 16:05
 */
@Aspect
@Component
public class NewsAspect {
    /**
     * @Description: 定义一个切点
     */
    @Pointcut("@annotation(com.test.common.NewsRecord)")
    public void newsRecord() {

    }

    /**
     * @description 方法执行后调用(不区分成功或异常)
     **/
    @After(value = "@annotation(newsRecord)", argNames = "newsRecord")
    public void after(NewsRecord newsRecord) {
        System.out.println("111---" + newsRecord.module());
        System.out.println("111---" + newsRecord.params());
        System.out.println("111---" + newsRecord.isDetail());

    }

}

(3)接口调用方法

@NewsRecord(module = "125", params = {"1", "2", "3"}, isDetail = false)
@GetMapping(value = "/getData")
public void listData() {
    System.out.println("111111");
}

(4) 接口调用执行结果

其中需要注意一个问题:

(1)小编是SpringBoot项目,其中将运行代码放到 main方法中会出现问题。

见下:

package com.test;

import com.test.common.NewsRecord;

/**
 * @Author tanghh
 * @Date 2019/12/1 15:52
 */
public class TestCommand {


  public static void main(String[]args){
      test();
  }
  @NewsRecord(module = "125",params = {"1","2","3"},isDetail = false)
  public static void test(){
      System.out.println("111111");
      System.out.println("111111");
      System.out.println("111111");
  }
}

运行出来的结果是:结果出乎意料,没有进aop拦截的方法。后面问了下同事,同事说是Springboot本身有一个启动方法,和当  前这个main方法是同一级的,所以不会进拦截的方法,换成接口访问就行了。

发布了46 篇原创文章 · 获赞 42 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tangthh123/article/details/103943286