• SpringMVC之自定义注解


    目录

    一.JAVA注解简介

     1.1.Java注解分类

    1.2.JDK元注解

    二.自定义注解

    1.1.如何自定义注解

     1.2.自定义注解的基本案例

    1.2.1.案例一(获取类与方法上的注解值)

     1.2.2.案例二(获取类属性上的注解属性值)

     1.2.3. 案例三(获取参数修饰注解对应的属性值)

     三.Aop自定义注解的应用

      好啦,今天的分享就到这了,希望能够帮到你呢!😊😊  


    一.JAVA注解简介

    Java注解是Java语言中一种元数据的形式,它是在程序源代码中插入的特殊标记,用于给程序中的代码提供额外的信息。注解可以用来为类、方法、字段等程序元素添加标记,以表明这些元素应该如何被处理或解析。

    Java注解是在编译时或运行时可以被读取和处理的。它们可以被用来提供编译器指令、在运行时进行跟踪和分析、生成代码和文档等。Java注解使用简单的语法进行声明,通常以@符号开头,紧跟注解的名称和一组可选的参数。

    Java提供了一些内置的注解,比如@Override用于标记一个方法重写了父类中的方法,@Deprecated用于标记一个已过时的方法或类,@SuppressWarnings用于抑制编译器警告等。此外,开发者也可以自定义注解来满足特定的需求。

    通过使用注解,开发者可以为自己的代码添加额外的信息,并通过工具或框架来读取和处理这些注解,以达到特定的目的。注解可以提高代码的可读性、维护性和可扩展性,是Java开发中一个非常有用的特性。

     1.1.Java注解分类

    JDK(Java Development Kit)提供了一些基本的注解和元注解,下面分别介绍它们的作用:

    1.基本注解:

    • @Override:用于标记一个方法是重写父类中的方法,如果该方法没有正确地重写父类的方法,则会在编译时报错。
    • @Deprecated:用于标记一个方法、类或字段已经过时,表示不推荐使用,编译器会在使用过时元素时发出警告。
    • @SuppressWarnings:用于抑制编译器产生的警告,可以在特定的代码块或者整个方法中使用,让编译器忽略特定的警告。

    2.元注解:

    • @Target:用于指定注解可以应用的目标元素类型,如类、字段、方法等。
    • @Retention:用于指定注解的保留策略,即注解在何时生效,包括源代码期、编译期和运行期。
    • @Documented:用于指定注解是否会包含在生成的文档中。
    • @Inherited:用于指定注解是否可以被子类继承。

    3.自定义注解:

    • 自定义注解是根据业务需求定义的注解,可以通过@interface关键字来声明,并可以在注解中定义元素和默认值。自定义注解的元素可以是基本类型、枚举、Class类型、String类型以及以上类型的一维数组。自定义注解可以通过@MyAnnotation的形式应用到目标元素上,如类、方法、字段等。可以通过反射机制读取和解析自定义注解,并根据注解的信息进行相应的处理。

    使用自定义注解可以增加代码的可读性和可维护性,同时也方便框架和工具对程序进行扩展和定制。

    1.2.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工具提取成文档.

    二.自定义注解

    1.1.如何自定义注解

    要自定义注解,需要使用@interface关键字来声明注解,并在注解中定义元素和默认值。以下是自定义注解的基本步骤:

    1. 使用@interface关键字声明一个注解,如 @interface MyAnnotation

    2. 在注解内部定义元素,并为元素指定默认值。注解的元素可以是基本类型、枚举、Class类型、String类型以及以上类型的一维数组。

    3. 在代码中应用自定义注解。可以在类、方法、字段等目标元素上使用自定义注解。

    4. 通过反射机制读取和解析自定义注解。可以使用Java的反射机制获取类、方法、字段的注解信息,根据注解的信息进行相应的处理。

    自定义注解可以根据具体的业务需求灵活定义,并通过反射机制读取和处理注解的信息。注解可以提高代码的可读性、可维护性和可扩展性,是Java开发中一个有用且强大的特性。

     以下是示例,演示了如何自定义一个简单的注解:主要在2.3.4上

    1. import java.lang.annotation.ElementType;
    2. import java.lang.annotation.Retention;
    3. import java.lang.annotation.RetentionPolicy;
    4. import java.lang.annotation.Target;
    5. @Retention(RetentionPolicy.RUNTIME)
    6. @Target(ElementType.METHOD)
    7. public @interface MyAnnotation {
    8. String value() default "";
    9. int count() default 0;
    10. }

    在上述例子中,MyAnnotation注解包含两个元素,一个是value,类型为String,默认值为空字符串;另一个是count,类型为int,默认值为0。

     使用了@Retention(RetentionPolicy.RUNTIME)元注解指定了注解在运行时保留,使用了@Target(ElementType.METHOD)元注解指定了注解可以应用在方法上。

    MyClass类使用了自定义注解@MyAnnotation,并为注解的元素valuecount指定了具体的值:

    1. @MyAnnotation(value = "Hello", count = 5)
    2. public class MyClass {
    3. @MyAnnotation(value = "World")
    4. private String name;
    5. @MyAnnotation(count = 3)
    6. public void myMethod() {
    7. // 方法体
    8. }
    9. }

     通过getAnnotation()方法获取MyAnnotation注解的实例,然后可以读取注解的元素值。

    1. Class clazz = MyClass.class;
    2. MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
    3. String value = annotation.value();
    4. int count = annotation.count();

     自定义注解可以根据具体的业务需求灵活定义,并通过反射机制读取和处理注解的信息。注解可以提高代码的可读性、可维护性和可扩展性,是Java开发中一个有用且强大的特性。

     1.2.自定义注解的基本案例

    创建完项目之后,找到 pom.xml 配置文件 ,进行项目引用导入。

    1. "1.0" encoding="UTF-8"?>
    2. "http://maven.apache.org/POM/4.0.0"
    3. 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. fzpzyssm
    8. 1.0-SNAPSHOT
    9. war
    10. fzpzyssm 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. fzpzyssm
    170. src/main/java
    171. **/*.xml
    172. src/main/resources
    173. *.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
    188. maven-clean-plugin
    189. 3.1.0
    190. maven-resources-plugin
    191. 3.0.2
    192. maven-compiler-plugin
    193. 3.8.0
    194. maven-surefire-plugin
    195. 2.22.1
    196. maven-war-plugin
    197. 3.2.2
    198. maven-install-plugin
    199. 2.5.2
    200. maven-deploy-plugin
    201. 2.8.2

    1.2.1.案例一(获取类与方法上的注解值)

    创建 TranscationModel 直接C到包里接口:

    1. package com.junlinyi.annotation.demo;
    2. public enum TranscationModel {
    3. Read, Write, ReadWrite;
    4. }

    创建 MyAnnotation1 直接C到包里接口

    1. package com.junlinyi.annotation.demo;
    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. }

     创建 MyAnnotation2 直接C到包里接口

    1. package com.junlinyi.annotation.demo;
    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. }

     创建 MyAnnotation3 直接C到包里接口

    1. package com.junlinyi.annotation.demo;
    2. import java.lang.annotation.*;
    3. /**
    4. * @author 君临沂
    5. * @site www.junlinyi.jly
    6. * @company 君氏集团
    7. * @create 2023-09-14-18:48
    8. *
    9. * MyAnnotation3注解可以用在方法上
    10. * 注解运行期也保留
    11. * 可继承
    12. */
    13. @Target(ElementType.METHOD)
    14. @Retention(RetentionPolicy.RUNTIME)
    15. @Inherited
    16. @Documented
    17. public @interface MyAnnotation3 {
    18. TranscationModel[] models() default TranscationModel.ReadWrite;
    19. }

     创建测试类进行自定义注解测试 Demo1 

    1. package com.junlinyi.annotation.demo;
    2. /**
    3. * @author 君临沂
    4. * @site www.junlinyi.jly
    5. * @company 君氏集团
    6. * @create 2023-09-14-19:00
    7. *
    8. * 获取类与方法上的注解值
    9. */
    10. @MyAnnotation1(name = "abc")
    11. public class Demo1 {
    12. @MyAnnotation1(name = "xyz")
    13. public 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. }

     创建测试类进行自定义注解测试 Demo1Test

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

     执行其中的方法( list )进行测试,输出结果如下 : 

     执行其中的方法( edit)进行测试,输出结果如下 :

     1.2.2.案例二(获取类属性上的注解属性值)

    场景自定义注解 TestAnnotation

    1. package com.junlinyi.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. * @author 君临沂
    8. * @site www.junlinyi.jly
    9. * @company 君氏集团
    10. * @create 2023-09-14-19:25
    11. */
    12. //@Retention(RetentionPolicy.SOURCE)
    13. @Retention(RetentionPolicy.RUNTIME)
    14. @Target(ElementType.FIELD)
    15. public @interface TestAnnotation {
    16. String value() default "默认value值";
    17. String what() default "这里是默认的what属性对应的值";
    18. }

     创建测试类进行自定义注解的测试 Demo2

    1. package com.junlinyi.annotation.demo2;
    2. /**
    3. * @author 君临沂
    4. * @site www.junlinyi.jly
    5. * @company 君氏集团
    6. * @create 2023-09-14-19:48
    7. *
    8. * 获取类属性上的注解属性值
    9. */
    10. public class Demo2 {
    11. @TestAnnotation(value = "这就是value对应的值_msg1", what = "这就是what对应的值_msg1")
    12. private static String msg1;
    13. // 当没有在注解中指定属性名,那么就是value
    14. @TestAnnotation("这就是value对应的值1")
    15. private static String msg2;
    16. @TestAnnotation(value = "这就是value对应的值2")
    17. private static String msg3;
    18. @TestAnnotation(what = "这就是what对应的值")
    19. private static String msg4;
    20. }

     创建测试类进行自定义注解的测试 Demo2Test

    1. package com.junlinyi.annotation.demo2;
    2. import org.junit.Test;
    3. /**
    4. * @author 君临沂
    5. * @site www.junlinyi.jly
    6. * @company 君氏集团
    7. * @create 2023-09-14-19:48
    8. */
    9. public class Demo2Test {
    10. @Test
    11. public void test1() throws Exception {
    12. TestAnnotation msg1 = Demo2.class.getDeclaredField("msg1").getAnnotation(TestAnnotation.class);
    13. System.out.println(msg1.value());
    14. System.out.println(msg1.what());
    15. }
    16. @Test
    17. public void test2() throws Exception{
    18. TestAnnotation msg2 = Demo2.class.getDeclaredField("msg2").getAnnotation(TestAnnotation.class);
    19. System.out.println(msg2.value());
    20. System.out.println(msg2.what());
    21. }
    22. @Test
    23. public void test3() throws Exception{
    24. TestAnnotation msg3 = Demo2.class.getDeclaredField("msg3").getAnnotation(TestAnnotation.class);
    25. System.out.println(msg3.value());
    26. System.out.println(msg3.what());
    27. }
    28. @Test
    29. public void test4() throws Exception{
    30. TestAnnotation msg4 = Demo2.class.getDeclaredField("msg4").getAnnotation(TestAnnotation.class);
    31. System.out.println(msg4.value());
    32. System.out.println(msg4.what());
    33. }
    34. }

     执行其中 test1 的方法进行测试,输出结果为 : 

    执行其中 test2 的方法进行测试,输出结果为 : 

     执行其中 test3 的方法进行测试,输出结果为 : 

     执行其中 test4 的方法进行测试,输出结果为 : 

     1.2.3. 案例三(获取参数修饰注解对应的属性值)

    创建自定义注解 IsNotNull 

    1. package com.junlinyi.annotation.demo3;
    2. import java.lang.annotation.*;
    3. /**
    4. * @author 君临沂
    5. * @site www.junlinyi.jly
    6. * @company 君氏集团
    7. * @create 2023-09-14-19:50
    8. *
    9. * 非空注解:使用在方法的参数上,false表示此参数可以为空,true不能为空
    10. */
    11. @Documented
    12. @Target({ElementType.PARAMETER})
    13. @Retention(RetentionPolicy.RUNTIME)
    14. public @interface IsNotNull {
    15. boolean value() default false;
    16. }

     创建测试类  Demo3

    1. package com.junlinyi.annotation.demo3;
    2. /**
    3. * @author 君临沂
    4. * @site www.junlinyi.jly
    5. * @company 君氏集团
    6. * @create 2023-09-14-19:50
    7. *
    8. * 获取参数修饰注解对应的属性值
    9. */
    10. public class Demo3 {
    11. public void hello1(@IsNotNull(true) String name) {
    12. System.out.println("hello:" + name);
    13. }
    14. public void hello2(@IsNotNull String name) {
    15. System.out.println("hello:" + name);
    16. }
    17. }

     创建测试类  Demo3Test进行方法测试

    1. package com.junlinyi.annotation.demo3;
    2. import org.junit.Test;
    3. import java.lang.reflect.Method;
    4. import java.lang.reflect.Parameter;
    5. /**
    6. * @author 君临沂
    7. * @site www.junlinyi.jly
    8. * @company 君氏集团
    9. * @create 2023-09-14-19:50
    10. */
    11. public class Demo3Test {
    12. @Test
    13. public void hello1() throws Exception {
    14. Demo3 demo3 = new Demo3();
    15. for (Parameter parameter : demo3.getClass().getMethod("hello1", String.class).getParameters()) {
    16. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    17. if(annotation != null){
    18. System.out.println(annotation.value());//true
    19. }
    20. }
    21. }
    22. @Test
    23. public void hello2() throws Exception {
    24. Demo3 demo3 = new Demo3();
    25. for (Parameter parameter : demo3.getClass().getMethod("hello2", String.class).getParameters()) {
    26. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    27. if(annotation != null){
    28. System.out.println(annotation.value());//false
    29. }
    30. }
    31. }
    32. // @requestParam
    33. // 默认情况下:传参为空,不会调用方法的,不为空会调用方法
    34. // requice=false:啥也不传参也会调用方法
    35. @Test
    36. public void hello3() throws Exception {
    37. // 模拟浏览器传递到后台的参数 解读@requestParam
    38. String name = "junlinyi";
    39. Demo3 demo3 = new Demo3();
    40. Method method = demo3.getClass().getMethod("hello1", String.class);
    41. for (Parameter parameter : method.getParameters()) {
    42. IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    43. if(annotation != null){
    44. System.out.println(annotation.value());//true
    45. if (annotation.value() && !"".equals(name)){
    46. method.invoke(demo3,name);
    47. }
    48. }
    49. }
    50. }
    51. }

     执行其中的方法( hello1 )进行测试,输出结果为 : 

    执行其中的方法( hello2 )进行测试,输出结果为 : 

    执行其中的方法( hello3 )进行测试,输出结果为 : 

     

     三.Aop自定义注解的应用

    AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,可以在程序运行期间通过动态代理方式实现对代码的横切关注点进行模块化管理。其中,自定义注解可以作为AOP的触发器,用于标记需要进行切面处理的目标对象或方法。

    以下是一个示例,演示了如何使用自定义注解与AOP结合,实现日志记录的功能:

      1 .定义自定义注解@MyLog,用于标记需要记录日志的方法:

    1. package com.junlinyi.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 君临沂
    8. * @site www.junlinyi.jly
    9. * @company 君氏集团
    10. * @create 2023-09-14-19:55
    11. *
    12. */
    13. @Target(ElementType.METHOD)
    14. @Retention(RetentionPolicy.RUNTIME)
    15. public @interface MyLog {
    16. String desc();
    17. }

    2 . 定义切面类MyLogAspect,在该类中定义增强逻辑,例如记录日志:

    1. package com.junlinyi.aspect;
    2. import org.aspectj.lang.ProceedingJoinPoint;
    3. import org.aspectj.lang.annotation.Around;
    4. import org.aspectj.lang.annotation.Aspect;
    5. import org.aspectj.lang.annotation.Pointcut;
    6. import org.slf4j.Logger;
    7. import org.slf4j.LoggerFactory;
    8. import org.springframework.stereotype.Component;
    9. import java.util.Arrays;
    10. /**
    11. * @author 君临沂
    12. * @site www.junlinyi.jly
    13. * @company 君氏集团
    14. * @create 2023-09-14-19:55
    15. *
    16. */
    17. @Component
    18. @Aspect
    19. public class MyLogAspect {
    20. private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class);
    21. /**
    22. * 只要用到了com.javaxl.p2.annotation.springAop.MyLog这个注解的,就是目标类
    23. */
    24. @Pointcut("@annotation(com.junlinyi.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. //
    33. // MyLog myLog = signature.getMethod().getAnnotation(MyLog.class);
    34. // logger.debug("【目标对象方法被调用时候产生的日志,记录到日志表中】:"+myLog.desc());
    35. // System.out.println("【目标对象方法被调用时候产生的日志,记录到日志表中】:" + myLog.desc());
    36. // }
    37. @Around("MyValid()")
    38. public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    39. long startTime = System.currentTimeMillis();
    40. System.out.println(pjp.getTarget());
    41. System.out.println(pjp.getThis());
    42. Object[] args = pjp.getArgs();
    43. System.out.println(Arrays.toString(args));
    44. Object ob = pjp.proceed();// ob 为方法的返回值
    45. System.out.println(ob);
    46. logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
    47. return ob;
    48. }
    49. }

    在上面的切面类中,使用@Aspect注解标记该类为切面类。@Pointcut("@annotation(com.CloudJun.annotation.aop.MyLog)")注解用于定义切点,表示匹配所有标记有@Log注解的方法。@Before注解表示在目标方法执行前执行增强逻辑。
     

     3 . 创建一个控制器 LogController 

    1. package com.junlinyi.web;
    2. import com.junlinyi.annotation.aop.MyLog;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import javax.servlet.http.HttpServletRequest;
    6. /**
    7. * @author 君临沂
    8. * @site www.junlinyi.jly
    9. * @company 君氏集团
    10. * @create 2023-09-14-19:56
    11. *
    12. */
    13. @Controller
    14. public class LogController {
    15. @RequestMapping("/myLog")
    16. @MyLog(desc = "日志管理")
    17. public void testLogAspect(HttpServletRequest request) {
    18. request.getRemoteAddr();
    19. request.getRemotePort();
    20. System.out.println("这里随便来点啥");
    21. }
    22. }

    自定义注解与AOP结合使用,可以实现各种不同的功能,如权限控制、性能监控、事务管理等。根据具体的业务需求,可以定义不同的注解,并在切面类中实现相应的增强逻辑。

    测试:

    处理中。。。。。

      好啦,今天的分享就到这了,希望能够帮到你呢!😊😊  

  • 相关阅读:
    【马蹄集】—— 数论专题
    中华保险面试题记录
    SpringBoot项目整合
    Jetpack Compose干货,如何让Compose Dialog从屏幕任意方向进入
    微信小程序案例2-1:学生信息
    今年嵌入式行情怎么样?
    设计模式六大原则
    python语言性能不适合在移动端做图色模拟开发,推荐用lua
    接口自动化测试框架postman tests常用方法
    git和github
  • 原文地址:https://blog.csdn.net/m0_74915426/article/details/132888351