精华内容
下载资源
问答
  • 转载请务必注明出处:One Coder-http://www.coderli.com/archives/eclipse-javadoc-template 项目中对于注释和代码...幸好Eclipse给我们提供了自定义代码模版的功能。 先说一下Java代码注释模版,它是指这里的配置...

    转载请务必注明出处:One Coder- http://www.coderli.com/archives/eclipse-javadoc-template

    项目中对于注释和代码规范的要求往往是毕比较严格的,如果全靠手动完成效率低,还难以保证保证的规范。幸好Eclipse给我们提供了自定义代码模版的功能。

     
    先说一下Java代码注释模版,它是指这里的配置:
     
     

     
    是不是跟你的不一样,多了@author和@date ?,恩,这是我自定义过的注释模版。效果是在给方法用/**注释内容*/,注释的时候,会生成如下形式的代码:
     

     
    ${tags}是生成@param,@return这些结果。其余的应该不用我多说了。
     
    定义这样的模版很简单,在刚才的位置,点Edit,按照如下的输入即可:
     
     
    这就够了?当然不是,如果在之前的方法忘记了@date时间注释,要怎么补上?直接用@ + 代码辅助?是不是找不到@date 标签?呵呵,当然,这个@date其实是我自定义的。定义的位置在这里:
     

     
    赶紧New一个 @date标签吧。
     
     
    注:Pattern中 @date字符为手动填写。后面两个变量为Eclipse内部提供的。
     
    保存看看效果?
     
     
    @date 出现了吧。
     
    是不是还想扩展Insert Variable里的内容?笔者也研究了一番,找到了这个:
     不过考虑到操作性价比,笔者并未尝试,有兴趣的朋友可以研究一下,欢迎交流。

    转载请务必注明出处:One Coder- http://www.coderli.com/archives/eclipse-javadoc-template



         本文转自mushiqianmeng 51CTO博客,原文链接:http://blog.51cto.com/mushiqianmeng/885701,如需转载请自行联系原作者



    展开全文
  • IntelliJ IDEA 自定义方法注解模板

    万次阅读 多人点赞 2017-08-02 18:04:36
    刚上手大概有一天,就知道它为啥取名为 intelli(智能化)了,确实很智能,这还是一些小小的细节,当然idea也有它不足之处,就是我们今天要讲的“自定义方法注解模板”,类注解模板可以很简单的设置,这里我就不重复...

     

    最近没啥事开始正式用Eclipse 转入 idea工具阵营,毕竟有70%的开发者在使用idea开发,所以它的魅力可想而知。刚上手大概有一天,就知道它为啥取名为 intelli(智能化)了,确实很智能,这还是一些小小的细节,当然idea也有它不足之处,就是我们今天要讲的“自定义方法注解模板”,类注解模板可以很简单的设置,这里我就不重复,而网上很多关于自定义方法注解模板的文章大多是抄袭获取转发根本自己就没有验证,本文经过自己亲自验证有效

     

    1. File->settings->Editor->Live Templates


       
    2. 点击右上角的绿色+号,然后选择template group ,然后输入group的name,随便输入就好了:myGroup。然后点ok


       
    3. 选中刚才创建的myGroup,然后再次点击右侧的绿色+,这次选择的是第一个1. Live Template。取名为*,取名可以随便,只是个人觉得方便,你可以取别的。
       

       
    4. 配置模板,下面是我的模板,大家仔细看我的模板开头是*而不是/*,这就是关键所在。
       
      *
       *  
       * 
       * @author chenmc
       * @date $date$ $time$
       * @param $params$
       * @return $returns$
       */
      注意:只有当变量被$$包围时 右侧的Edit variables才可以点击哦。

       
    5. 再编辑好模板之后就只为参数添加$$添加变量,点击右侧的 Editor variables,


       
    6. 完成之后点击Apply然后点击OK,注意了,重点的地方,在你的方法上输入 /*然后加上模板的名称*,这就是我为什么不取字母而取名为*,因为这样很快速,再按Tab键(注意啊不是按Enter键,而是按Tab键)就会出现你想要的注释了,很多教程是直接输入模板名称按tab键,但是这种方法的@param和@return是获取不到的,再重复一遍正确的方式:/** 然后按Tab键;如果你取名为abc那就是  /*abc 然后按Tab。效果如下:


       
    7. 但是还有一个问题,细心的读者会发现在@param这个参数上报错了,这是因为idea强大的检查功能,有两种解决办法:
       
      第一种:File->settings->Editor->Inspections->javadoc issues下面第四项将红色 Error改为黄色Warning即可
      第二种:点击idea的右下角的人头图像,然后选择高亮级别,调为Syntax模式即可



      至此已大功告成了,希望能帮到大家!

      对本教程如有疑问请关注微信公众号:裸睡的猪,获取帮助!!!

       
    展开全文
  • 深入JAVA注解(Annotation):自定义注解

    万次阅读 多人点赞 2019-07-31 18:40:53
    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。 元注解:  元注解的作用就是负责注解其他注解。Java5.0定义了4...

    一、基础知识:元注解

     

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。

    元注解:

      元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
        1.@Target,
        2.@Retention,
        3.@Documented,
        4.@Inherited
      这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。

      @Target:

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

      作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

      取值(ElementType)有:

        1.CONSTRUCTOR:用于描述构造器
        2.FIELD:用于描述域
        3.LOCAL_VARIABLE:用于描述局部变量
        4.METHOD:用于描述方法
        5.PACKAGE:用于描述包
        6.PARAMETER:用于描述参数
        7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

      使用实例:  

    复制代码

    @Target(ElementType.TYPE)
    public @interface Table {
        /**
         * 数据表名称注解,默认值为类名称
         * @return
         */
        public String tableName() default "className";
    }
    
    @Target(ElementType.FIELD)
    public @interface NoDBColumn {
    
    }

    复制代码

      注解Table 可以用于注解类、接口(包括注解类型) 或enum声明,而注解NoDBColumn仅可用于注解类的成员变量。

      @Retention:

      @Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。

      作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

      取值(RetentionPoicy)有:

        1.SOURCE:在源文件中有效(即源文件保留)
        2.CLASS:在class文件中有效(即class保留)
        3.RUNTIME:在运行时有效(即运行时保留)

      Retention meta-annotation类型有唯一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。具体实例如下:

    复制代码

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Column {
        public String name() default "fieldName";
        public String setFuncName() default "setField";
        public String getFuncName() default "getField"; 
        public boolean defaultDBValue() default false;
    }

    复制代码

       Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理

      @Documented:

      @Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

    复制代码

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Column {
        public String name() default "fieldName";
        public String setFuncName() default "setField";
        public String getFuncName() default "getField"; 
        public boolean defaultDBValue() default false;
    }

    复制代码

      @Inherited:

      @Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

      注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

      当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

     

    实例代码:

    复制代码

    /**
     * 
     * @author peida
     *
     */
    @Inherited
    public @interface Greeting {
        public enum FontColor{ BULE,RED,GREEN};
        String name();
        FontColor fontColor() default FontColor.GREEN;
    }

    二、基础知识:自定义注解

     

    使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

      定义注解格式:
      public @interface 注解名 {定义体}

      注解参数的可支持数据类型:

        1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
        2.String类型
        3.Class类型
        4.enum类型
        5.Annotation类型
        6.以上所有类型的数组

      Annotation类型里面的参数该怎么设定: 
      第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   
      第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
      第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。

      简单的自定义注解和使用注解实例:

    复制代码

    package annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 水果名称注解
     * @author peida
     *
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface FruitName {
        String value() default "";
    }

    复制代码

    复制代码

    package annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 水果颜色注解
     * @author peida
     *
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface FruitColor {
        /**
         * 颜色枚举
         * @author peida
         *
         */
        public enum Color{ BULE,RED,GREEN};
        
        /**
         * 颜色属性
         * @return
         */
        Color fruitColor() default Color.GREEN;
    
    }

    复制代码

    复制代码

    package annotation;
    
    import annotation.FruitColor.Color;
    
    public class Apple {
        
        @FruitName("Apple")
        private String appleName;
        
        @FruitColor(fruitColor=Color.RED)
        private String appleColor;
        
        
        
        
        public void setAppleColor(String appleColor) {
            this.appleColor = appleColor;
        }
        public String getAppleColor() {
            return appleColor;
        }
        
        
        public void setAppleName(String appleName) {
            this.appleName = appleName;
        }
        public String getAppleName() {
            return appleName;
        }
        
        public void displayName(){
            System.out.println("水果的名字是:苹果");
        }
    }

    复制代码


    注解元素的默认值:

      注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。因此, 使用空字符串或0作为默认值是一种常用的做法。这个约束使得处理器很难表现一个元素的存在或缺失的状态,因为每个注解的声明中,所有元素都存在,并且都具有相应的值,为了绕开这个约束,我们只能定义一些特殊的值,例如空字符串或者负数,一次表示某个元素不存在,在定义注解时,这已经成为一个习惯用法。

    三、自定义注解实例

         以上都是一些注解的基础知识,这里讲一下自定义注解的使用。一般,注解都是搭配反射的解析器共同工作的,然后利用反射机制查看类的注解内容。如下:

     

    复制代码

     1 package testAnnotation;
     2 
     3 import java.lang.annotation.Documented;
     4 import java.lang.annotation.Retention;
     5 import java.lang.annotation.RetentionPolicy;
     6 
     7 @Documented
     8 @Retention(RetentionPolicy.RUNTIME)
     9 public @interface Person{
    10     String name();
    11     int age();
    12 }

    复制代码

     

     package testAnnotation;
     2 
     3 @Person(name="xingoo",age=25)
     4 public class test3 {
     5     public static void print(Class c){
     6         System.out.println(c.getName());
     7         
     8         //java.lang.Class的getAnnotation方法,如果有注解,则返回注解。否则返回null
     9         Person person = (Person)c.getAnnotation(Person.class);
    10         
    11         if(person != null){
    12             System.out.println("name:"+person.name()+" age:"+person.age());
    13         }else{
    14             System.out.println("person unknown!");
    15         }
    16     }
    17     public static void main(String[] args){
    18         test3.print(test3.class);
    19     }
    20 }

     

    运行结果:

    testAnnotation.test3
    name:xingoo age:25

    接下来再讲一个工作中的例子就可以收篇啦!

    LoginVerify注解是用于对标注的方法在进行请求访问时进行登录判断。

     

    package com.newsee.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 是否已登录判断
     *
     */
    @Documented
    @Target(ElementType.METHOD)
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LoginVerify {
    
    }

     

    ScanningLoginVerifyAnnotation里的scanning()方法被@PostConstruct修饰,说明它在服务器加载Servlet的时候运行,并且只会被服务器执行一次。

     

    这里再科普一下:

     

    @PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有如下两种方式:

    @PostConstruct

    Public void someMethod() {}                                                                       
    或者

    public @PostConstruct void someMethod(){}

    被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct会在构造函数之后,init()方法之前执行。PreDestroy()方法在destroy()方法执行之后执行

     

    scanning方法是在servlet加载完毕后获取所有被加载类,遍历其中的方法,如果有被LoginVerify注解修饰,则该方法名放到一个static的map中存储起来。

     

     

    package com.newsee.annotation;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    import javax.annotation.PostConstruct;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.core.io.support.ResourcePatternResolver;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ClassUtils;
    import com.newsee.constant.LoginVerifyMapping;
    
    @Component
    public class ScanningLoginVerifyAnnotation {
    	private static final String PACKAGE_NAME = "com.newsee.face";
    
    	private static final String RESOURCE_PATTERN = "/**/*.class";
    
    	@PostConstruct
    	public void scanning() throws IOException, SecurityException,
    			ClassNotFoundException {
    		String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
    				+ ClassUtils.convertClassNameToResourcePath(PACKAGE_NAME)
    				+ RESOURCE_PATTERN;
    		ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    		Resource[] resources = resourcePatternResolver.getResources(pattern);
    		for (Resource resource : resources) {
    			if (resource.isReadable()) {
    				String className = getClassName(resource.getURL().toString());
    				Class cls = ScanningRequestCodeAnnotation.class.getClassLoader().loadClass((className));
    				for (Method method : cls.getMethods()) {
    					LoginVerify requestCode = method.getAnnotation(LoginVerify.class);
    					if (requestCode != null) {
    						</span>LoginVerifyMapping.add(className + "."+ method.getName());
    					}
    				}
    			}
    		}
    	}
    
    	private String getClassName(String resourceUrl) {
    		String url = resourceUrl.replace("/", ".");
    		url = url.replace("\\", ".");
    		url = url.split("com.newsee")[1];
    		url = url.replace(".class", "");
    		return "com.newsee" + url.trim();
    	}
    }
    

    LoginVerifyMapping就是存放被LoginVerify注解修饰的方法名的。

    public class LoginVerifyMapping {
    	private static Map<String, Boolean> faceFunctionIsNeedLoginVerify = new HashMap<String, Boolean>();
    
    	public static void add(String functionName) {
    		faceFunctionIsNeedLoginVerify.put(functionName, Boolean.TRUE);
    	}
    
    	public static Boolean getFaceFunctionIsNeedLoginVerify(String functionName) {
    		return faceFunctionIsNeedLoginVerify.get(functionName);
    	}
    }

    以下方法就是请求过来时判断请求的方法是不是在LoginVerifyMapping中,如果是,则需要进行登录校验。

    private ResponseContent handleRequests(RequestContent requestContent) throws ClassNotFoundException,
    			NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
    			InvocationTargetException {
    		String requestCode = requestContent.getRequest().getHead().getNWCode();
    		String className = RequestCodeMapping.getClassName(requestCode);
    		String beanName = RequestCodeMapping.getBeanName(requestCode);
    		String functionName = RequestCodeMapping.getFunctionName(requestCode);
    		Boolean loginVerify = LoginVerifyMapping.getFaceFunctionIsNeedLoginVerify(className + "." + functionName);
    		if (loginVerify != null && loginVerify) {//需要进行登录校验
    			boolean isAuthenticated = SecurityUtils.getSubject().isAuthenticated();
    			if (!isAuthenticated) {
    				String exId=requestContent.getRequest().getHead().getNWExID();
    				SystemMobileTokenKeyServiceInter systemMobileTokenKeyServiceInter = (SystemMobileTokenKeyServiceInter) SpringContextUtil
    					.getBean("systemMobileTokenKeyServiceInter");
    				SystemMobileTokenKey systemMobileTokenKey=systemMobileTokenKeyServiceInter.getByExId(exId);
    				if(systemMobileTokenKey==null)
    					throw new BaseException(ResponseCodeEnum.NO_LOGIN);
    				Date keyTime = systemMobileTokenKey.getKeyTime();
    				if (System.currentTimeMillis() - keyTime.getTime() > 1000 * 60 * 60 * 24 * 3)
    					throw new BaseException(ResponseCodeEnum.NO_LOGIN);
    			}
    		}
    		if (className == null || beanName == null || functionName == null)
    			throw new BaseException(ResponseCodeEnum.REQUEST_CODE_NOT_EXIST);
    		Object object = SpringContextUtil.getBean(beanName);
    		Class cls = Class.forName(className);
    		Method method = cls.getMethod(functionName, RequestContent.class);
    		Object response = method.invoke(object, requestContent);
    		return (ResponseContent) response;
    	}
    }

     

     

     

     

    展开全文
  • 自定义校验注解

    2020-11-18 16:21:21
    以后开发过程中,关于参数合法性的校验,如果有已实现的注解(例如@NotNull、@NotEmpty等)可以直接使用,没有现成的可用,尽量使用自定义注解,使得业务逻辑与校验分离,校验逻辑复用,代码结构清晰。 需求:接收...

    目录

    1. 自定义校验注解步骤

    2. 自定义校验注解

    2.1 基本语法

    2.2 几个元注解

    3. 创建验证器

    4. 使用注解

    5. 利用反射获取注解


    API开发中经常会遇到一些对请求数据进行验证的情况,这时候如果使用注解就有两个好处。

    • 一是验证逻辑和业务逻辑分离,代码清晰;
    • 二是验证逻辑可以轻松复用,只需要在要验证的地方加上注解就可以。

    以后开发过程中,关于参数合法性的校验,如果有已实现的注解(例如@NotNull、@NotEmpty等)可以直接使用,没有现成的可用,尽量使用自定义注解,使得业务逻辑与校验分离,校验逻辑复用,代码结构清晰。

    需求:接收一个Student对象,并希望对象里的age域的值是奇数。下面以此需求为例,解析自定义校验注解。

    1. 自定义校验注解步骤

    1. 一个自定义的注解,并且指定验证器
    2. 一个验证器的实现

    2. 自定义校验注解

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = AgeValidator.class)
    public @interface Odd {
        String message() default "Age Must Be Odd";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }

    2.1 基本语法

    注解里面定义的是:注解类型元素!

    1. 访问修饰符必须为public,不写默认为public;
    2. 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组;
    3. 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(使用的时候可以省略指定key,默认即为value);
    4. ()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
    5. default代表默认值,值必须和第2点定义的类型一致;
    6. 如果没有默认值,代表后续使用注解时必须给该类型元素赋值。

    可以看出,注解类型元素的语法非常奇怪,即又有属性的特征(可以赋值),又有方法的特征(打上了一对括号)。但是这么设计是有道理的:注解在定义好了以后,使用的时候操作元素类型像在操作属性,解析的时候操作元素类型像在操作方法

    2.2 几个元注解

    • @Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。它使用一个枚举类型定义,包括:TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE等;
    • @Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。可以有RetentionPolicy.SOURCE(仅保存在源码中,会被编译器丢弃),RetentionPolicy.CLASS(在class文件中可用,会被VM丢弃)以及RetentionPolicy.RUNTIME(在运行期也被保留),这里选择了生命周期最长的RetentionPolicy.RUNTIME;
    • @Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
    • @Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。
    • @Constraint是最关键的,它表示这个注解是一个验证注解,并且指定了一个实现验证逻辑的验证器
    • message()指明了验证失败后返回的消息,此方法为@Constraint要求
    • groups()payload()也为@Constraint要求,可默认为空,详细用途可以查看@Constraint文档

    3. 创建验证器

    public class AgeValidator implements ConstraintValidator<Odd,Integer> {
        @Override
        public void initialize(Odd constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) {
            return age % 2 != 0;
        }
    }

    其中,

    • 验证器ConstraintValidator有两个类型参数,第一个是所属的注解,第二个是注解作用地方的类型,这里因为作用在age上,因此这里用了Integer;
    • initialize()可以在验证开始前调用注解里的方法,从而获取到一些注解里的参数,这里用不到;
    • isValid()就是判断是否合法的地方,参数age就是所验证字段的实际值;

    4. 使用注解

    注解和验证器创建好之后,就可以使用注解了

    @RestController
    public class StudentResource {
        @PostMapping("/student")
        public String addStudent(@Valid @RequestBody Student student) {
            return "Student Created";
        }
    }
    public class Student {
        @Odd
        private int age;
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }

    在需要启用验证的地方加上@Valid注解,这时候如果请求里的Student年龄不是奇数,就会得到一个400响应,这时候注意设置全局异常处理,异常响应体如下:

    {
        "timestamp": "2018-08-15T17:01:44.598+0000",
        "status": 400,
        "error": "Bad Request",
        "errors": [
            {
                "codes": [
                    "Odd.student.age",
                    "Odd.age",
                    "Odd.int",
                    "Odd"
                ],
                "arguments": [
                    {
                        "codes": [
                            "student.age",
                            "age"
                        ],
                        "arguments": null,
                        "defaultMessage": "age",
                        "code": "age"
                    }
                ],
                "defaultMessage": "Age Must Be Odd",
                "objectName": "student",
                "field": "age",
                "rejectedValue": 12,
                "bindingFailure": false,
                "code": "Odd"
            }
        ],
        "message": "Validation failed for object='student'. Error count: 1",
        "path": "/student"
    }

    5. 利用反射获取注解

    public class TestAnnotation {
        public static void main(String[] args){
            try {
                //获取Student的Class对象
                Class stuClass = Class.forName("pojos.Student");
    
                //说明一下,这里形参不能写成Integer.class,应写为int.class
                Method stuMethod = stuClass.getMethod("study",int.class);
    
                if(stuMethod.isAnnotationPresent(TestAnnotation.class)){
                    System.out.println("Student类上配置了TestAnnotation注解!");
                    //获取该元素上指定类型的注解
                    TestAnnotation testAnnotation = stuMethod.getAnnotation(TestAnnotation.class);
                    System.out.println("name: " + TestAnnotation.name() + ", age: " + TestAnnotation.age()
                        + ", score: " + TestAnnotation.score()[0]);
                }else{
                    System.out.println("Student类上没有配置TestAnnotation注解!");
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
    

    其中,

    1.  如果我们要获得的注解是配置在方法上的,那么我们要从Method对象上获取;如果 是配置在属性上,就需要从该属性对应的Field对象上去获取,如果是配置在类型 上,需要从Class对象上去获取。总之在谁身上,就从谁身上去获取!
    2. isAnnotationPresent(Class annotationClass) 方法是专门判 断该元素上是否配置有某个指定的注解;
    3. getAnnotation(Class<A> annotationClass) 方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据;
    4. 反射对象上还有一个方法 getAnnotations() ,该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于java.lang.annotation包的接口。
    展开全文
  • spring 自定义注解 翻看公司代码,看到了自定义注解,查了查,再次记录一下,还是太菜 下面是我的实现 1. 自定义注解 package com.test; import javax.validation.Constraint; import javax.validation.Payload; ...
  • 一丶自定义注解

    2019-10-24 10:49:10
    1.Spring自定义注解: public @interface MyAnnotation { } 自定义的的注解需要添加元注解(或者一些默认的值配置) 常用的4种元注解: java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的...
  • 自定义注解会需要元注解,此处先介绍元注解。 元注解 java中有四种元注解:@Retention、@Inherited、@Documented、@Target @Retention 注解的保留位置(枚举RetentionPolicy),RetentionPolicy可选值: ...
  • java自定义校验注解

    千次阅读 2019-03-31 16:22:06
    随着业务的日趋复杂。我们对客户端传来的参数校验也越来越多。...如果自定义一个注解呢? 使用Idea进行创建 选择Annotation类型 这样我们就成功创建了一个注解。 刚创建出来的注解是不能使用的。因...
  • Java中的注解以及自定义注解

    万次阅读 多人点赞 2019-05-30 16:21:53
    注意标红的反射两个字,反射在注解里相当重要,写完你的自定义注解类后没啥用,必须要用反射才能让它动起来!所以需要对反射有了解,感兴趣的小可爱可以看下这篇:Java中的反射机制介绍 (2)、从 JDK 5.0 开...
  • springboot自定义日志注解

    千次阅读 2018-05-23 20:26:03
    指定自定义注解 @Pointcut ( "@annotation(com.cf.utils.annotation.SysLog)" ) public void logPointCut() { } @Before ( "logPointCut()" ) public void saveSysLog(JoinPoint joinPoint) { ...
  • 自定义java注解

    2016-04-28 11:19:49
    一、什么是java注解  注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的。  Java注解又叫java标注,java提供了一套...二、自定义Java标注 1 为
  • 一、Java元注解 java中元注解:@Retention、@Inherited、@Documented、@Target ps : retention [rɪˈtenʃn] 保留 Inherited [ɪn’herɪtɪd] 继承 @Retention 注解的保留位置(枚举RetentionPolicy),...
  • 自定义注解详细介绍

    万次阅读 多人点赞 2018-07-10 16:03:21
    1 注解的概念 1.1 注解的官方定义 首先看看官方对注解的描述: An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and ...
  • 自定义注解

    2018-11-29 18:15:22
    自定义注解主要是在jdk1.5之后提供的一种语法,其主要作用是编译检查(比如@override)和代码分析(通过代码中添加注解,利用注解解析器对添加了注解的代码进行分析,获取想要的结果,一般自定义注解都是这一种...
  • 在我们日常开发中,经常使用Enable注解来开启某些功能。例如 EnableDiscoveryClient EnableFeignClients @EnableAuthorizationServer .... 我们发现这些注解都是用来开启某些功能的,其实如果...
  • 自定义自定义注解解析

    千次阅读 2018-08-07 16:35:57
    java.lang.annotation 提供了四种元注解,可以用来注解其他的注解,像Override这些注解都会用到它们,我们自定义注解的时候也会用到,四种注解如下: @Target:说明注解用于什么地方。 @Retention:什么时候使用...
  • 初学spring的时候使用注解总觉得使用注解很神奇,加一个注解就能实现想要的功能,很好奇,也想自己根据需要写一些自己实现的自定义注解。问题来了,自定义注解到底是什么?肯定会有人和我一样有这个疑惑,我根据自己...
  • 一,注解基本概念 从JDK1.5开始,Java提供了对元数据(MetaData)的支持,也就是注解(Annotation) 注解,其实就是代码中的特殊标记,这些特殊标记可以在类加载,编译,运行时被读取,并执行相应的处理 使用注解最大的作用就是...
  • 题目:自定义注解@Order:排序以下方法的执行顺序 package com.yunhe.test; // 使用自定义注解实现方法的排序执行 import com.yunhe.annotation.Order; public class RunOrder { @Order(value = 1) public ...
  • 自定义Java注解(一)

    2016-12-11 20:38:30
    概念注解是Java语言5.0版本开始支持加入源代码的特殊语法元数据(描述数据的数据)有点像Class(描述类的类)要自定义注解,必须先了解Java提供的几个基本的元注解及其相关的语法Java的几个元注解 @Target @Retention...
  • 前一编博文讲述了注解实现和应用,其中有一个涉及到自定注解的地方,本文就这个问题继续写与这相关的一,编写自定义注解需要的基础知识, 编写自定义注解需要使用的Java元注解,有四种元注解:@Retention、@...
  • Java 自定义注解

    2019-11-06 19:48:28
    Java自定义注解Java注解简介Java元注解自定义注解代码演示 本章点知识总览: 1、Java 注解简介 2、Java 元注解(重点) 3、自定义注解 4、Aop 自定义注解的应用(重点) Java注解(Annotation) 分类 编程技术 Java...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,063
精华内容 6,025
关键字:

自定义javadoc注解

java 订阅