• springmvc之自定义注解-->自定义注解简介,基本案例和aop自定义注解


    • 自定义注解简介
    • 自定义注解基本案例
    • aop自定义注解

    1.自定义注解简介

    1.基本注解

    2.元注解

    3.自定义注解

             3.1.标记注解

             3.2.元数据注解

             3.3.自定义注解语法:@interface

    JDK基本注解
    @Override
    重写

    @SuppressWarnings(value = "unchecked")
    压制编辑器警告

    JDK元注解

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

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

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

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

    自定义注解

    注解分类(根据Annotation是否包含成员变量,可以把Annotation分为两类):

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

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

    如何自定义注解?
    使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:
       Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型,
       而且我们还可以使用default关键字为这个成员变量设定默认值;

    2.自定义注解基本案例

    案例一

    1. //pom.xml
    2. "1.0" encoding="UTF-8"?>
    3. "http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. 4.0.0
    6. org.example
    7. zljzyssm
    8. 1.0-SNAPSHOT
    9. war
    10. zljzyssm Maven Webapp
    11. http://www.example.com
    12. UTF-8
    13. 1.8
    14. 1.8
    15. 3.7.0
    16. 5.0.2.RELEASE
    17. 3.4.5
    18. 5.1.44
    19. 5.1.2
    20. 1.3.1
    21. 2.1.1
    22. 2.4.3
    23. 2.9.1
    24. 3.2.0
    25. 1.7.13
    26. 4.12
    27. 4.0.0
    28. 1.18.2
    29. 1.1.0
    30. 2.10.0
    31. 2.9.0
    32. 1.7.1.RELEASE
    33. 2.9.3
    34. 1.2
    35. 1.1.2
    36. 8.0.47
    37. 1.3.3
    38. 5.0.2.Final
    39. 1.3.2
    40. org.springframework
    41. spring-core
    42. ${spring.version}
    43. org.springframework
    44. spring-beans
    45. ${spring.version}
    46. org.springframework
    47. spring-context
    48. ${spring.version}
    49. org.springframework
    50. spring-orm
    51. ${spring.version}
    52. org.springframework
    53. spring-tx
    54. ${spring.version}
    55. org.springframework
    56. spring-aspects
    57. ${spring.version}
    58. org.springframework
    59. spring-web
    60. ${spring.version}
    61. org.springframework
    62. spring-test
    63. ${spring.version}
    64. org.mybatis
    65. mybatis
    66. ${mybatis.version}
    67. mysql
    68. mysql-connector-java
    69. ${mysql.version}
    70. com.github.pagehelper
    71. pagehelper
    72. ${pagehelper.version}
    73. org.mybatis
    74. mybatis-spring
    75. ${mybatis.spring.version}
    76. org.springframework
    77. spring-context-support
    78. ${spring.version}
    79. org.mybatis.caches
    80. mybatis-ehcache
    81. ${mybatis.ehcache.version}
    82. net.sf.ehcache
    83. ehcache
    84. ${ehcache.version}
    85. redis.clients
    86. jedis
    87. ${redis.version}
    88. org.springframework.data
    89. spring-data-redis
    90. ${redis.spring.version}
    91. com.fasterxml.jackson.core
    92. jackson-databind
    93. ${jackson.version}
    94. com.fasterxml.jackson.core
    95. jackson-core
    96. ${jackson.version}
    97. com.fasterxml.jackson.core
    98. jackson-annotations
    99. ${jackson.version}
    100. org.apache.commons
    101. commons-dbcp2
    102. ${commons.dbcp2.version}
    103. commons-pool2
    104. org.apache.commons
    105. org.apache.commons
    106. commons-pool2
    107. ${commons.pool2.version}
    108. org.springframework
    109. spring-webmvc
    110. ${spring.version}
    111. org.slf4j
    112. slf4j-api
    113. ${slf4j.version}
    114. org.slf4j
    115. jcl-over-slf4j
    116. ${slf4j.version}
    117. runtime
    118. org.apache.logging.log4j
    119. log4j-api
    120. ${log4j2.version}
    121. org.apache.logging.log4j
    122. log4j-core
    123. ${log4j2.version}
    124. org.apache.logging.log4j
    125. log4j-slf4j-impl
    126. ${log4j2.version}
    127. org.apache.logging.log4j
    128. log4j-web
    129. ${log4j2.version}
    130. runtime
    131. com.lmax
    132. disruptor
    133. ${log4j2.disruptor.version}
    134. junit
    135. junit
    136. ${junit.version}
    137. javax.servlet
    138. javax.servlet-api
    139. ${servlet.version}
    140. provided
    141. org.projectlombok
    142. lombok
    143. ${lombok.version}
    144. provided
    145. jstl
    146. jstl
    147. ${jstl.version}
    148. taglibs
    149. standard
    150. ${standard.version}
    151. org.apache.tomcat
    152. tomcat-jsp-api
    153. ${tomcat-jsp-api.version}
    154. commons-fileupload
    155. commons-fileupload
    156. ${commons-fileupload.version}
    157. org.hibernate
    158. hibernate-validator
    159. ${hibernate-validator.version}
    160. org.apache.shiro
    161. shiro-core
    162. ${shiro.version}
    163. org.apache.shiro
    164. shiro-web
    165. ${shiro.version}
    166. org.apache.shiro
    167. shiro-spring
    168. ${shiro.version}
    169. zljzyssm
    170. src/main/java
    171. **/*.xml
    172. src/main/resources
    173. jdbc.properties
    174. *.xml
    175. org.apache.maven.plugins
    176. maven-compiler-plugin
    177. ${maven.compiler.plugin.version}
    178. ${maven.compiler.source}
    179. ${maven.compiler.target}
    180. ${project.build.sourceEncoding}
    181. org.mybatis.generator
    182. mybatis-generator-maven-plugin
    183. 1.3.2
    184. mysql
    185. mysql-connector-java
    186. ${mysql.version}
    187. true
    1. package com.zlj.annotation.demo1;
    2. public enum TranscationModel {
    3. Read, Write, ReadWrite;
    4. private String name;
    5. private Integer id;
    6. public void init1(){
    7. Read.id=1;
    8. Read.name="zs";
    9. }
    10. public void init2(){
    11. Write.id=2;
    12. Write.name="ls";
    13. }
    14. public void init3(){
    15. ReadWrite.id=3;
    16. ReadWrite.name="ww";
    17. }
    18. }
    1. package com.zlj.annotation.demo1;
    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.zlj.annotation.demo1;
    2. import java.lang.annotation.*;
    3. /**
    4. * MyAnnotation2注解可以用在方法上
    5. * 注解运行期也保留
    6. * 不可继承
    7. */
    8. @Target(ElementType.METHOD)
    9. @Retention(RetentionPolicy.RUNTIME)
    10. @Documented
    11. public @interface MyAnnotation2 {
    12. TranscationModel model() default TranscationModel.ReadWrite;
    13. }
    1. package com.zlj.annotation.demo1;
    2. import java.lang.annotation.*;
    3. /**
    4. * MyAnnotation3注解可以用在方法上
    5. * 注解运行期也保留
    6. * 可继承
    7. */
    8. @Target(ElementType.METHOD)
    9. @Retention(RetentionPolicy.RUNTIME)
    10. @Inherited //继承使用时需要该注解,否则读取不到该继承的注解及属性
    11. @Documented
    12. public @interface MyAnnotation3 {
    13. TranscationModel[] models() default TranscationModel.ReadWrite;
    14. }
    1. package com.zlj.annotation;
    2. import com.zlj.annotation.demo1.TranscationModel;
    3. /**
    4. * @author zlj
    5. * @create 2023-09-14 19:32
    6. */
    7. public class Test1 {
    8. public static void main(String[] args) {
    9. System.out.println(TranscationModel.Read);
    10. System.out.println(TranscationModel.Write);
    11. System.out.println(TranscationModel.ReadWrite);
    12. }
    13. }
    1. package com.zlj.annotation;
    2. import com.zlj.annotation.demo1.MyAnnotation1;
    3. import com.zlj.annotation.demo1.MyAnnotation2;
    4. import com.zlj.annotation.demo1.MyAnnotation3;
    5. import com.zlj.annotation.demo1.TranscationModel;
    6. /**
    7. *
    8. * 获取类与方法上的注解值
    9. */
    10. @MyAnnotation1(name = "abc")
    11. public class Demo1 {
    12. @MyAnnotation1(name = "xyz")
    13. private Integer age;
    14. @MyAnnotation2(model = TranscationModel.Read)
    15. public void list() {
    16. System.out.println("list");
    17. }
    18. @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    19. public void edit() {
    20. System.out.println("edit");
    21. }
    22. }
    1. package com.zlj.annotation;
    2. import com.zlj.annotation.demo1.MyAnnotation1;
    3. import com.zlj.annotation.demo1.MyAnnotation2;
    4. import com.zlj.annotation.demo1.MyAnnotation3;
    5. import com.zlj.annotation.demo1.TranscationModel;
    6. import org.junit.Test;
    7. /**
    8. * @site www.javaxl.com
    9. */
    10. public class Demo1Test {
    11. @Test
    12. public void list() throws Exception {
    13. // 获取类上的注解
    14. MyAnnotation1 annotation1 = Demo1.class.getAnnotation(MyAnnotation1.class);
    15. System.out.println(annotation1.name());//abc
    16. // 获取方法上的注解
    17. MyAnnotation2 myAnnotation2 = Demo1.class.getMethod("list").getAnnotation(MyAnnotation2.class);
    18. System.out.println(myAnnotation2.model());//Read
    19. // 获取属性上的注解
    20. MyAnnotation1 myAnnotation1 = Demo1.class.getDeclaredField("age").getAnnotation(MyAnnotation1.class);
    21. System.out.println(myAnnotation1.name());// xyz
    22. }
    23. @Test
    24. public void edit() throws Exception {
    25. MyAnnotation3 myAnnotation3 = Demo1.class.getMethod("edit").getAnnotation(MyAnnotation3.class);
    26. for (TranscationModel model : myAnnotation3.models()) {
    27. System.out.println(model);//Read,Write
    28. }
    29. }
    30. }

    案例二

    1. package com.zlj.annotation.demo2;
    2. /**
    3. * @site www.javaxl.com
    4. *
    5. * 获取类属性上的注解属性值
    6. */
    7. public class Demo2 {
    8. @TestAnnotation(value = "这就是value对应的值_msg1", what = "这就是what对应的值_msg1")
    9. private static String msg1;
    10. //当没有在注解中指定属性名,那么就是value
    11. @TestAnnotation("这就是value对应的值1")
    12. private static String msg2;
    13. @TestAnnotation(value = "这就是value对应的值2")
    14. private static String msg3;
    15. @TestAnnotation(what = "这就是what对应的值")
    16. private static String msg4;
    17. }
    1. package com.zlj.annotation.demo2;
    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. /**
    7. * @site www.javaxl.com
    8. */
    9. //@Retention(RetentionPolicy.SOURCE)
    10. @Retention(RetentionPolicy.RUNTIME)
    11. @Target(ElementType.FIELD)
    12. public @interface TestAnnotation {
    13. String value() default "默认value值";
    14. String what() default "这里是默认的what属性对应的值";
    15. }
    1. package com.zlj.annotation.demo2;
    2. import org.junit.Test;
    3. /**
    4. * @site www.javaxl.com
    5. */
    6. public class Demo2Test {
    7. @Test
    8. public void test1() throws Exception {
    9. TestAnnotation msg1 = Demo2.class.getDeclaredField("msg1").getAnnotation(TestAnnotation.class);
    10. System.out.println(msg1.value());
    11. System.out.println(msg1.what());
    12. }
    13. @Test
    14. public void test2() throws Exception{
    15. TestAnnotation msg2 = Demo2.class.getDeclaredField("msg2").getAnnotation(TestAnnotation.class);
    16. System.out.println(msg2.value());
    17. System.out.println(msg2.what());
    18. }
    19. @Test
    20. public void test3() throws Exception{
    21. TestAnnotation msg3 = Demo2.class.getDeclaredField("msg3").getAnnotation(TestAnnotation.class);
    22. System.out.println(msg3.value());
    23. System.out.println(msg3.what());
    24. }
    25. @Test
    26. public void test4() throws Exception{
    27. TestAnnotation msg4 = Demo2.class.getDeclaredField("msg4").getAnnotation(TestAnnotation.class);
    28. System.out.println(msg4.value());
    29. System.out.println(msg4.what());
    30. }
    31. }

    总结:在Demo2中如果指定了value和what值,那么在DemoTest2运行结果就是Demo2里的value和what值;

    在Demo2中如果没有在注解中指定属性名,那么就是value,在DemoTest2运行结果就是Demo2的value值和TestAnnotation里的what值;

    在Demo2中如果只指定了value值,在DemoTest2运行结果也是Demo2的value值和TestAnnotation里的what值;

    在Demo2中如果只指定了what值,在DemoTest2运行结果就是TestAnnotation里的value值和Demo2的what值;

    方案三

    1. package com.zlj.annotation.demo3;
    2. import java.lang.annotation.*;
    3. /**
    4. * @author zlj
    5. * @site www.javaxl.com
    6. *
    7. * 非空注解:使用在方法的参数上,false表示此参数可以为空,true不能为空
    8. */
    9. @Documented
    10. @Target({ElementType.PARAMETER})
    11. @Retention(RetentionPolicy.RUNTIME)
    12. public @interface IsNotNull {
    13. boolean value() default false;
    14. }
    1. package com.zlj.annotation.demo3;
    2. /**
    3. * @author zlj
    4. * @site www.javaxl.com
    5. *
    6. * 获取参数修饰注解对应的属性值
    7. */
    8. public class Demo3 {
    9. public void hello1(@IsNotNull(true) String name) {
    10. System.out.println("hello:" + name);
    11. }
    12. public void hello2(@IsNotNull String name) {
    13. System.out.println("hello:" + name);
    14. }
    15. }
    1. package com.zlj.annotation.demo3;
    2. import org.junit.Test;
    3. import java.lang.reflect.Method;
    4. import java.lang.reflect.Parameter;
    5. /**
    6. * @author zlj
    7. * @site www.javaxl.com
    8. */
    9. public class Demo3Test {
    10. @Test
    11. public void hello1() throws Exception {
    12. Demo3 demo3 = new Demo3();
    13. for (Parameter parameter : demo3.getClass().getMethod("hello1", String.class).getParameters()) {
    14. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    15. if(annotation != null){
    16. System.out.println(annotation.value());//true
    17. }
    18. }
    19. }
    20. @Test
    21. public void hello2() throws Exception {
    22. Demo3 demo3 = new Demo3();
    23. for (Parameter parameter : demo3.getClass().getMethod("hello2", String.class).getParameters()) {
    24. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    25. if(annotation != null){
    26. System.out.println(annotation.value());//false
    27. }
    28. }
    29. }
    30. @Test
    31. public void hello3() throws Exception {
    32. // 模拟浏览器传递到后台的参数 解读@requestParam
    33. String name = "zs";
    34. Demo3 demo3 = new Demo3();
    35. Method method = demo3.getClass().getMethod("hello1", String.class);
    36. for (Parameter parameter : method.getParameters()) {
    37. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    38. if(annotation != null){
    39. System.out.println(annotation.value());//true
    40. if (annotation.value() && !"".equals(name)){
    41. method.invoke(demo3,name);
    42. }
    43. }
    44. }
    45. }
    46. }

    注解案例知识点:

    1.获取类,方法,属性,修饰参数上的注解

    2.关于注解上的value属性设置值是可以省略的

    3.Inhereted案例演示,体现类上面的注解的继承性

    4.default值的使用

    3.aop自定义注解

    1. package com.zlj.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. /**
    7. * @author zlj
    8. * @site www.javaxl.com
    9. */
    10. @Target(ElementType.METHOD)
    11. @Retention(RetentionPolicy.RUNTIME)
    12. public @interface MyLog {
    13. String desc();
    14. }
    1. package com.zlj.web;
    2. import com.zlj.annotation.aop.MyLog;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. /**
    6. * @author zlj
    7. * @site www.javaxl.com
    8. */
    9. @Controller
    10. public class LogController {
    11. @RequestMapping("/mylog")
    12. @MyLog(desc = "这是结合spring aop知识,讲解自定义注解应用的一个案例")
    13. public void testLogAspect(){
    14. System.out.println("这里随便来点啥");
    15. }
    16. }
    1. package com.zlj.aspect;
    2. import com.zlj.annotation.aop.MyLog;
    3. import org.aspectj.lang.JoinPoint;
    4. import org.aspectj.lang.annotation.Aspect;
    5. import org.aspectj.lang.annotation.Before;
    6. import org.aspectj.lang.annotation.Pointcut;
    7. import org.aspectj.lang.reflect.MethodSignature;
    8. import org.slf4j.Logger;
    9. import org.slf4j.LoggerFactory;
    10. import org.springframework.stereotype.Component;
    11. /**
    12. * @author zlj
    13. * @site www.javaxl.com
    14. */
    15. @Component
    16. @Aspect
    17. public class MyLogAspect {
    18. private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class);
    19. /**
    20. * 只要用到了com.javaxl.p2.annotation.springAop.MyLog这个注解的,就是目标类
    21. * * *..Biz. *pager(..)
    22. * execution
    23. */
    24. @Pointcut("@annotation(com.zlj.annotation.aop.MyLog)")
    25. private void MyValid() {
    26. }
    27. @Before("MyValid()")
    28. public void before(JoinPoint joinPoint) {
    29. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    30. logger.debug("[" + signature.getName() + " : start.....]");
    31. System.out.println("[" + signature.getName() + " : start.....]");
    32. MyLog myLog = signature.getMethod().getAnnotation(MyLog.class);
    33. logger.debug("【目标对象方法被调用时候产生的日志,记录到日志表中】:"+myLog.desc());
    34. System.out.println("【目标对象方法被调用时候产生的日志,记录到日志表中】:" + myLog.desc());
    35. }
    36. }

  • 相关阅读:
    HDLbits: ece241 2014 q7b
    万应案例精选|跨壁垒、辅决策,万应低代码助力国网电力内部培训数字化架构升级
    [C++随想录] 优先级队列的模拟实现
    【commons-beanutils专题】005- ConvertUtils 专题
    【1024程序员节特刊】算法题目易错之处干货总结
    Java 之 IO/NIO/OKIO
    华为ICT——第二章-数字图像处理私人笔记
    Arthas之类操作
    rabbitmq 面试题
    市面上出现的led灯什么牌子的质量好?五款质量好的led灯分享
  • 原文地址:https://blog.csdn.net/weixin_73471776/article/details/132888093