zoukankan      html  css  js  c++  java
  • java自定义注解

    1. Java注解(Annotation)

       Java注解是附加在代码中的一些元信息,用于一些工具在编译、

       运行时进行解析和使用,起到说明、配置的功能。

     

       注解相关类都包含在java.lang.annotation包中。

     

    2. Java注解分类

      2.1 JDK基本注解

      2.2 JDK元注解

      2.3 自定义注解

     

    3. JDK基本注解

      3.1 @Override

          重写

      3.2 @Deprecated

          已过时

      3.3 @SuppressWarnings(value = "unchecked")

          压制编辑器警告

     

     

    Java元注解

     

    作用:元注解用于修饰其他的注解

     

    @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关键字为这个成员变量设定默认值;

     

     

     

    注意:只有名字为value”属性,赋值时可以省略属性名

     

     

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

     

    package com.ssm.yuan.p1;
    
    
    public enum  TranscationModel {
        Read, Write, ReadWrite
    }

     

     1 package com.ssm.yuan.p1;
     2 
     3 import java.lang.annotation.*;
     4 
     5 /**
     6  *
     7  * MyAnnotation3注解可以用在方法上
     8  * 注解运行期也保留
     9  * 可继承
    10  */
    11 @Target(ElementType.METHOD)
    12 @Retention(RetentionPolicy.RUNTIME)
    13 @Inherited
    14 @Documented
    15 public @interface MyAnnotation3 {
    16     TranscationModel[] models() default TranscationModel.ReadWrite;
    17 }

     

     1 package com.ssm.yuan.p1;
     2 
     3 import java.lang.annotation.*;
     4 
     5 /**
     6  *
     7  *  MyAnnotation2注解可以用在方法上
     8  *  注解运行期也保留
     9  *  不可继承
    10  */
    11 @Target(ElementType.METHOD)
    12 @Retention(RetentionPolicy.RUNTIME)
    13 @Documented
    14 public @interface MyAnnotation2 {
    15     TranscationModel model() default TranscationModel.ReadWrite;
    16 }

     

     

     1 package com.ssm.yuan.p1;
     2 
     3 import java.lang.annotation.*;
     4 
     5 /**
     6  *
     7  * MyAnnotation1注解可以用在类、接口、属性、方法上
     8  * 注解运行期也保留
     9  * 不可继承
    10  */
    11 @Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
    12 @Retention(RetentionPolicy.RUNTIME)
    13 @Documented
    14 public @interface MyAnnotation1 {
    15     String name();
    16 }

     

     

     1 package com.ssm.yuan.p1;
     2 
     3 import org.junit.Test;
     4 
     5 /**
     6  *
     7  */
     8 public class Demo1Test {
     9     @Test
    10     public void list() throws Exception {
    11 //        获取类上的注解
    12         MyAnnotation1 annotation1 = Demo1.class.getAnnotation(MyAnnotation1.class);
    13         System.out.println(annotation1.name());//abc
    14 
    15 //        获取方法上的注解
    16         MyAnnotation2 myAnnotation2 = Demo1.class.getMethod("list").getAnnotation(MyAnnotation2.class);
    17         System.out.println(myAnnotation2.model());//Read
    18 
    19 
    20 
    21     }
    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.ssm.yuan.p1;
     2 
     3 /**
     4  *
     5  * 获取类与方法上的注解值
     6  */
     7 @MyAnnotation1(name = "abc")
     8 public class Demo1 {
     9 
    10     @MyAnnotation1(name = "xyz")
    11     private Integer age;
    12 
    13     @MyAnnotation2(model = TranscationModel.Read)
    14     public void list() {
    15         System.out.println("list");
    16     }
    17 
    18     @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
    19     public void edit() {
    20         System.out.println("edit");
    21     }
    22 }

     

    案例一测试结果

     

     

     

     

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

     

     

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

     

     

     1 package com.ssm.yuan.p2;
     2 
     3 /**
     4  *
     5  * 获取类属性上的注解属性值
     6  */
     7 public class Demo2 {
     8     @TestAnnotation(value = "这就是value对应的值_msg1", what = "这就是what对应的值_msg1")
     9     private static String msg1;
    10 
    11     @TestAnnotation("这就是value对应的值1")
    12     private static String msg2;
    13 
    14     @TestAnnotation(value = "这就是value对应的值2")
    15     private static String msg3;
    16 
    17     @TestAnnotation(what = "这就是what对应的值")
    18     private static String msg4;
    19 }

     

     1 package com.ssm.yuan.p2;
     2 
     3 import org.junit.Test;
     4 
     5 /**
     6  */
     7 public class Demo2Test {
     8     @Test
     9     public void test1() throws Exception {
    10         TestAnnotation msg1 = Demo2.class.getDeclaredField("msg1").getAnnotation(TestAnnotation.class);
    11         System.out.println(msg1.value());
    12         System.out.println(msg1.what());
    13     }
    14 
    15     @Test
    16     public void test2() throws Exception{
    17         TestAnnotation msg2 = Demo2.class.getDeclaredField("msg2").getAnnotation(TestAnnotation.class);
    18         System.out.println(msg2.value());
    19         System.out.println(msg2.what());
    20     }
    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 
    29     @Test
    30     public void test4() throws Exception{
    31         TestAnnotation msg4 = Demo2.class.getDeclaredField("msg4").getAnnotation(TestAnnotation.class);
    32         System.out.println(msg4.value());
    33         System.out.println(msg4.what());
    34     }
    35 }

     

     

     

     

     

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

     

     

     1 package com.ssm.yuan.p3;
     2 
     3 import java.lang.annotation.*;
     4 
     5 /**
     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.ssm.yuan.p3;
     2 
     3 /**
     4  *
     5  * 获取参数修饰注解对应的属性值
     6  */
     7 public class Demo3 {
     8 
     9     public void hello1(@IsNotNull(true) String name, @IsNotNull(false) Integer age) {
    10         System.out.println("hello:" + name);
    11     }
    12 
    13     public void hello2(@IsNotNull String name) {
    14         System.out.println("hello:" + name);
    15     }
    16 }

     

     

     1 package com.ssm.yuan.p3;
     2 
     3 import org.junit.Test;
     4 
     5 import java.lang.reflect.Parameter;
     6 
     7 /**
     8  */
     9 public class Demo3Test {
    10 
    11     @Test
    12     public void hello1() throws Exception {
    13         Demo3 demo3 = new Demo3();
    14         for (Parameter parameter : demo3.getClass().getMethod("hello1", String.class, Integer.class).getParameters()) {
    15             IsNotNull annotation = parameter.getAnnotation(IsNotNull.class);
    16             if(annotation != null){
    17                 System.out.println(annotation.value());//true
    18             }
    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 }

     

     

     Aop自定义注解的应用

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

    Controller层

     1 package com.ssm.yuan.controller;
     2 
     3 import com.ssm.yuan.springaop.MyLog;
     4 import org.springframework.stereotype.Component;
     5 
     6 /**
     7  */
     8 @Component
     9 public class LogController {
    10 
    11     @MyLog(desc = "这是结合spring aop知识,讲解自定义注解应用的一个案例")
    12     public void testLogAspect(){
    13         System.out.println("随便写点东西。。。。");
    14     }
    15 }

    SpringBaseTest

    package com.ssm.yuan;
    
    import com.ssm.yuan.model.Surfaceregistration;
    import com.ssm.jt.util.PageBean;
    import org.junit.Before;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:spring.xml"})
    public class SpringBaseTest {
    
    }

    Controller层测试

     1 package com.ssm.yuan.controller;
     2 
     3 import com.ssm.yuan.SpringBaseTest;
     4 import org.junit.Test;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 
     7 /**
     8  */
     9 public class LogControllerTest extends SpringBaseTest {
    10     @Autowired
    11     private LogController logController;
    12 
    13     @Test
    14     public void testLogAspect(){
    15         logController.testLogAspect();
    16     }
    17 }

    也可参考:https://blog.csdn.net/qq_43059674/article/details/102912359(aop实现注解式数据字典)

     

    谢谢观看!!!

     

  • 相关阅读:
    python中的矩阵运算
    【python问题系列--4】ValueError: operands could not be broadcast together with shapes (100,3) (3,1)
    【Machine Learning in Action --4】朴素贝叶斯从个人广告中获取区域倾向
    php使用数组语法访问对象
    curl: (60) SSL certificate problem: unable to get local issuer certificate 错误
    php 回调、匿名函数和闭包
    php5.3 延迟静态绑定 static关键字
    利用redis完成自动补全搜索功能(三)
    利用redis完成自动补全搜索功能(二)
    利用redis完成自动补全搜索功能(一)
  • 原文地址:https://www.cnblogs.com/ly-0919/p/11921806.html
Copyright © 2011-2022 走看看