• SpringMVC:从入门到精通,7篇系列篇带你全面掌握--七.自定义注解


    目录

    🥳🥳Welcome Huihui's Code World ! !🥳🥳

    一.Java注解简介

    1.原生注解的分类

    (1)JDK基本注解

            ①@Override

            ②@SuppressWarnings(value = "unchecked")

    (2)JDK元注解

            ①@Retention

            ②@Target

            ③@Source

            ④@Inherited

    (3)自定义注解

            ①标记注解

            ②元数据注解

    2.如何自定义注解

    二.自定义注解的各种使用情况

    1.获取类与方法上的注解值

    2.获取类属性上的注解属性值

    3.获取参数修饰注解对应的属性值

    三.AOP结合自定义注解完成案例 

    1.自定义注解

    ①使用@interface关键字定义注解接口

    ②为注解添加元素(可选)

    ③使用元注解(如@Retention、@Target等)对注解进行配置

    2.应用注解


    🥳🥳Welcome Huihui's Code World ! !🥳🥳

    接下来看看由辉辉所写的关于SpringMVC的相关操作吧

    一.Java注解简介

            Java注解(Annotation)是一种用于描述代码的元数据,它可以用于为代码提供额外的信息,以便在编译、运行时或者其他阶段对代码进行处理。注解不会影响代码的实际逻辑,仅作为一种标记。Java注解可以应用于类、方法、变量、参数等元素

    1.原生注解的分类

    (1)JDK基本注解

    下面介绍两种常用的JDK元原生注解

            ①@Override

                 @Override是Java中的一个注解,用于表示一个方法是重写了父类的方法。当一个方法被标注为@Override时,编译器会检查该方法是否正确地重写了父类的方法。如果没有正确地重写父类的方法,编译器会报错

            ②@SuppressWarnings(value = "unchecked")

                 @SuppressWarnings是Java中的一个注解,用于告诉编译器忽略指定的警告信息。这个注解通常用于处理代码中的某些问题,例如类型转换警告、未经检查的异常等

                 @SuppressWarnings注解有以下几种用法:

                    ①@SuppressWarnings(value = "unchecked"):忽略未经检查的异常警告。

                    ②@SuppressWarnings(value = {"unchecked", "deprecation"}):忽略未经检查的                        异常和已弃用的警告。

                    ③@SuppressWarnings("unchecked"):忽略未经检查的异常警告。

                    ④@SuppressWarnings({"unchecked", "deprecation"}):忽略未经检查的异常和已                         弃用的警告

    1. public class SuppressWarningsExample {
    2. public static void main(String[] args) {
    3. // 使用@SuppressWarnings注解忽略未经检查的异常警告
    4. @SuppressWarnings("unchecked")
    5. void myMethod() {
    6. List rawList = new ArrayList();
    7. List stringList = rawList; // 这里会产生未经检查的异常警告
    8. }
    9. }
    10. }

    (2)JDK元注解

            ①@Retention

    1. @Retention:定义注解的保留策略
    2. @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
    3. @Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
    4. @Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到

            ②@Target

    1. @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标)
    2. @Target(ElementType.TYPE) //接口、类
    3. @Target(ElementType.FIELD) //属性
    4. @Target(ElementType.METHOD) //方法
    5. @Target(ElementType.PARAMETER) //方法参数
    6. @Target(ElementType.CONSTRUCTOR) //构造函数
    7. @Target(ElementType.LOCAL_VARIABLE) //局部变量
    8. @Target(ElementType.ANNOTATION_TYPE) //注解
    9. @Target(ElementType.PACKAGE) //包
    10. 注:可以指定多个位置,例如:
    11. @Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和类上面使用

            ③@Source

    @Inherited:指定被修饰的Annotation将具有继承性
    

            ④@Inherited

    @inherited 注解用于指示子类是否继承父类的注解。当在父类上使用了 @inherited 注解时,子类会自动继承该注解。但要注意,@inherited 注解仅适用于类级别的注解,对于方法、字段等其他元素级别的注解不起作用

    @Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档.

    (3)自定义注解

    根据Annotation是否包含成员变量,可以把Annotation分为两类

            ①标记注解

    没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息

            ②元数据注解

    包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据

    2.如何自定义注解

    使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:
       Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型,
       而且我们还可以使用default关键字为这个成员变量设定默认值(这里只是简略见一下,后面会结合案例详细讲解自定义注解的步骤)

    二.自定义注解的各种使用情况

    需要的依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <parent>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <version>2.3.7.RELEASEversion>
    9. <relativePath/>
    10. parent>
    11. <groupId>com.zkinggroupId>
    12. <artifactId>spboottest01artifactId>
    13. <version>0.0.1-SNAPSHOTversion>
    14. <name>spboottest01name>
    15. <description>Demo project for Spring Bootdescription>
    16. <properties>
    17. <java.version>8java.version>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starter-webartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframework.bootgroupId>
    26. <artifactId>spring-boot-starter-testartifactId>
    27. dependency>
    28. dependencies>
    29. <build>
    30. <plugins>
    31. <plugin>
    32. <groupId>org.springframework.bootgroupId>
    33. <artifactId>spring-boot-maven-pluginartifactId>
    34. plugin>
    35. plugins>
    36. build>
    37. project>

    1.获取类与方法上的注解值

    1. package com.wh.annotation;
    2. public enum TranscationModel {
    3. Read, Write, ReadWrite
    4. }
    1. package com.wh.annotation.pi;
    2. import java.lang.annotation.*;
    3. /**
    4. * MyAnnotation1注解可以用在类、接口、属性、方法上
    5. * 注解运行期也保留
    6. * 不可继承
    7. */
    8. @Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
    9. @Retention(RetentionPolicy.RUNTIME)
    10. @Documented
    11. public @interface MyAnnotation1 {
    12. String name();
    13. }
    1. package com.wh.annotation.pi;
    2. import com.wh.annotation.TranscationModel;
    3. import java.lang.annotation.*;
    4. /**
    5. * MyAnnotation2注解可以用在方法上
    6. * 注解运行期也保留
    7. * 不可继承
    8. */
    9. @Target(ElementType.METHOD)
    10. @Retention(RetentionPolicy.RUNTIME)
    11. @Documented
    12. public @interface MyAnnotation2 {
    13. TranscationModel model() default TranscationModel.ReadWrite;
    14. }
    1. package com.wh.annotation.pi;
    2. import com.wh.annotation.TranscationModel;
    3. import java.lang.annotation.*;
    4. /**
    5. * @author 小李飞刀
    6. * @site www.javaxl.com
    7. *
    8. * MyAnnotation3注解可以用在方法上
    9. * 注解运行期也保留
    10. * 可继承
    11. */
    12. @Target(ElementType.METHOD)
    13. @Retention(RetentionPolicy.RUNTIME)
    14. @Inherited
    15. @Documented
    16. public @interface MyAnnotation3 {
    17. TranscationModel[] models() default TranscationModel.ReadWrite;
    18. }
    1. package com.wh.annotation.demo;
    2. import com.wh.annotation.TranscationModel;
    3. import com.wh.annotation.pi.MyAnnotation1;
    4. import com.wh.annotation.pi.MyAnnotation2;
    5. import com.wh.annotation.pi.MyAnnotation3;
    6. @MyAnnotation1(name = "abc")
    7. public class Demo1 {
    8. @MyAnnotation1(name = "xyz")
    9. private Integer age;
    10. @MyAnnotation2(model = TranscationModel.Read)
    11. public void list() {
    12. System.out.println("list");
    13. }
    14. @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    15. public void edit() {
    16. System.out.println("edit");
    17. }
    18. }

    测试

    1. package com.wh.annotation.demo;
    2. import com.wh.annotation.TranscationModel;
    3. import com.wh.annotation.pi.MyAnnotation1;
    4. import com.wh.annotation.pi.MyAnnotation2;
    5. import com.wh.annotation.pi.MyAnnotation3;
    6. import org.junit.Test;
    7. public class Demo1Test {
    8. @Test
    9. public void list() throws Exception {
    10. // 获取类上的注解
    11. MyAnnotation1 annotation1 = Demo1.class.getAnnotation(MyAnnotation1.class);
    12. System.out.println(annotation1.name());//abc
    13. // 获取方法上的注解
    14. MyAnnotation2 myAnnotation2 = Demo1.class.getMethod("list").getAnnotation(MyAnnotation2.class);
    15. System.out.println(myAnnotation2.model());//Read
    16. // 获取属性上的注解
    17. MyAnnotation1 myAnnotation1 = Demo1.class.getDeclaredField("age").getAnnotation(MyAnnotation1.class);
    18. System.out.println(myAnnotation1.name());// xyz
    19. }
    20. @Test
    21. public void edit() throws Exception {
    22. MyAnnotation3 myAnnotation3 = Demo1.class.getMethod("edit").getAnnotation(MyAnnotation3.class);
    23. for (TranscationModel model : myAnnotation3.models()) {
    24. System.out.println(model);//Read,Write
    25. }
    26. }
    27. }

    2.获取类属性上的注解属性值

    1. package com.wh.annotation.p2;
    2. import java.lang.annotation.ElementType;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. //@Retention(RetentionPolicy.SOURCE)
    7. @Retention(RetentionPolicy.RUNTIME)
    8. @Target(ElementType.FIELD)
    9. public @interface TestAnnotation {
    10. String value() default "默认value值";
    11. String what() default "这里是默认的what属性对应的值";
    12. }

    测试

    1. package com.wh.annotation.demo2;
    2. import com.wh.annotation.p2.TestAnnotation;
    3. public class Demo2 {
    4. @TestAnnotation(value = "这就是value对应的值_msg1", what = "这就是what对应的值_msg1")
    5. private static String msg1;
    6. @TestAnnotation("这就是value对应的值1")
    7. private static String msg2;
    8. @TestAnnotation(value = "这就是value对应的值2")
    9. private static String msg3;
    10. @TestAnnotation(what = "这就是what对应的值")
    11. private static String msg4;
    12. }
    1. package com.wh.annotation.demo2;
    2. import com.wh.annotation.p2.TestAnnotation;
    3. import org.junit.Test;
    4. public class Demo2Test {
    5. @Test
    6. public void test1() throws Exception {
    7. TestAnnotation msg1 = Demo2.class.getDeclaredField("msg1").getAnnotation(TestAnnotation.class);
    8. System.out.println(msg1.value());
    9. System.out.println(msg1.what());
    10. }
    11. @Test
    12. public void test2() throws Exception{
    13. TestAnnotation msg2 = Demo2.class.getDeclaredField("msg2").getAnnotation(TestAnnotation.class);
    14. System.out.println(msg2.value());
    15. System.out.println(msg2.what());
    16. }
    17. @Test
    18. public void test3() throws Exception{
    19. TestAnnotation msg3 = Demo2.class.getDeclaredField("msg3").getAnnotation(TestAnnotation.class);
    20. System.out.println(msg3.value());
    21. System.out.println(msg3.what());
    22. }
    23. @Test
    24. public void test4() throws Exception{
    25. TestAnnotation msg4 = Demo2.class.getDeclaredField("msg4").getAnnotation(TestAnnotation.class);
    26. System.out.println(msg4.value());
    27. System.out.println(msg4.what());
    28. }
    29. }

    3.获取参数修饰注解对应的属性值

    1. package com.wh.annotation.p3;
    2. import java.lang.annotation.*;
    3. /**
    4. *
    5. *
    6. * 非空注解:使用在方法的参数上,false表示此参数可以为空,true不能为空
    7. */
    8. @Documented
    9. @Target({ElementType.PARAMETER})
    10. @Retention(RetentionPolicy.RUNTIME)
    11. public @interface IsNotNull {
    12. boolean value() default false;
    13. }
    1. package com.wh.annotation.demo3;
    2. import com.wh.annotation.p3.IsNotNull;
    3. /**
    4. *
    5. * 获取参数修饰注解对应的属性值
    6. */
    7. public class Demo3 {
    8. public void hello1(@IsNotNull(true) String name) {
    9. System.out.println("hello:" + name);
    10. }
    11. public void hello2(@IsNotNull String name) {
    12. System.out.println("hello:" + name);
    13. }
    14. }

    三.AOP结合自定义注解完成案例 

    1.自定义注解

    ①使用@interface关键字定义注解接口

    1. package com.wh.annotation.aop;
    2. import java.lang.annotation.ElementType;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. @Target(ElementType.METHOD)
    7. @Retention(RetentionPolicy.RUNTIME)
    8. public @interface MyLog {
    9. String desc();
    10. }

    ②为注解添加元素(可选)

    ③使用元注解(如@Retention@Target等)对注解进行配置

    1. package com.wh.annotation.aop;
    2. import java.lang.annotation.ElementType;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. @Target(ElementType.METHOD)
    7. @Retention(RetentionPolicy.RUNTIME)
    8. public @interface MyLog {
    9. String desc();
    10. }
    1. package com.wh.annotation.aop;
    2. import org.aspectj.lang.JoinPoint;
    3. import org.aspectj.lang.annotation.Aspect;
    4. import org.aspectj.lang.annotation.Before;
    5. import org.aspectj.lang.annotation.Pointcut;
    6. import org.aspectj.lang.reflect.MethodSignature;
    7. import org.slf4j.Logger;
    8. import org.slf4j.LoggerFactory;
    9. import org.springframework.stereotype.Component;
    10. @Component
    11. @Aspect
    12. public class MyLogAspect {
    13. private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class);
    14. /**
    15. * 只要用到了com.javaxl.p2.annotation.springAop.MyLog这个注解的,就是目标类
    16. */
    17. @Pointcut("@annotation(com.wh.annotation.aop.MyLog)")
    18. private void MyValid() {
    19. }
    20. @Before("MyValid()")
    21. public void before(JoinPoint joinPoint) {
    22. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    23. logger.debug("[" + signature.getName() + " : start.....]");
    24. System.out.println("[" + signature.getName() + " : start.....]");
    25. MyLog myLog = signature.getMethod().getAnnotation(MyLog.class);
    26. logger.debug("【目标对象方法被调用时候产生的日志,记录到日志表中】:"+myLog.desc());
    27. System.out.println("【目标对象方法被调用时候产生的日志,记录到日志表中】:" + myLog.desc());
    28. }
    29. }

    2.应用注解

    1. package com.wh.annotation.aop;
    2. import org.springframework.stereotype.Component;
    3. @Component
    4. public class LogController {
    5. @MyLog(desc = "这是结合spring aop知识,讲解自定义注解应用的一个案例")
    6. public void testLogAspect(){
    7. System.out.println("这里随便来点啥");
    8. }
    9. }
    1. package com.wh.annotation.aop;
    2. import org.junit.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. /**
    5. * @author 小李飞刀
    6. * @site www.javaxl.com
    7. */
    8. public class LogControllerTest {
    9. @Autowired
    10. private LogController logController;
    11. @Test
    12. public void testLogAspect(){
    13. logController.testLogAspect();
    14. }
    15. }

  • 相关阅读:
    Web3游戏的十字路口:沿用传统IP还是另起炉灶?
    Hive 中的各种常用set设置
    Java后端开发(十一)-- Mysql8的详细安装与环境配置
    Python学习基础笔记十二——文件
    linux文件操作
    将彩色图转化为灰度图及其原理介绍
    深入了解 XXE 注射
    原码、反码、补码小结
    沥青拦水带成型机摊铺作业急工地之所急
    leetcode 字符串
  • 原文地址:https://blog.csdn.net/m0_74315688/article/details/132888140