Java注解之自定义注解实现

Java中的注解:
分类一:jdk内置注解(元注解)

@Documented -注解是否将包含在JavaDoc中
@Retention  -什么时候使用该注解(生命周期)
	RetentionPolicy.SOURCE: 在变异阶段丢弃,这些注解在编译结束之后就不再有任何意义,所以不会写入到字节码中
	RetentionPolicy.CLASS: 在类加载的时候丢弃,在字节码文件的处理中有用,注解默认使用方式
	RetentionPolicy.RUNTIME: 始终不会丢弃,运行器也保留该注解,因此可以使用反射机制读取该注解的信息,自定义注解通常使用这个方式。
@Target     -注解用于什么地方
	ElementType.CONSTRUCTOR: 用于描述构造器
	ElementType.FIELD: 成员变量,对象,属性(包括enum实例)
	ElementType.LOCAL_VARIABLE: 用于描述局部变量
	ElementType.METHOD:用于描述方法
	ElementType.PACKAGE: 用于描述包
	ElementType.PARAMETER: 用于描述参数
	ElementType.TYPE: 用于描述类,接口或enum声明
@Inherited  -是否允许子类继承该注解

分类二: 第三方框架
分类三:自定义注解:
一、自定义注解类编写规则:

  1. Annotation 型定义为@interface, 所有的Annotation会自动集成java.lang.Annotation这个接口,并且不会集成别的类或是接口。
  2. 参数成员只能用public或者是默认(default) 这两种访问权修饰。
  3. 参数成员只能用八大基础数据类型和String, Enum, Class, annotations 等数据类型,以及这些类型的数组。
  4. 注解方法不能带有参数。
  5. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取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 lizhonghao
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Drinks {
    public enum Category{SOFT_DRINK, MAD_CROC};

    Category categoryType() default Category.SOFT_DRINK;
}
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 lizhonghao
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DrinkProvider {
    public int id() default -1;
    public String name() default "";
    public String address() default "";

}

实现注解的功能

/**
 * 注解处理器
 * @author lizhonghao
 */
public class DrinksImpl {


    public static void drinkInfo(Class clazz) {

        String category = "饮料类型:";
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
             if (field.isAnnotationPresent(Drinks.class)) {
                Drinks categoryType = field.getAnnotation(Drinks.class);
                 category = category + categoryType.categoryType().toString();
                System.out.println(category);
            }
            else if (field.isAnnotationPresent(DrinkProvider.class)) {
                DrinkProvider drinkProvider = field.getAnnotation(DrinkProvider.class);
                 String  strDrinkProvicer = "供应商编号: " + drinkProvider.id() + "供应商名称:" + drinkProvider.name() + "供应商地址: " + drinkProvider.address();
                System.out.println(strDrinkProvicer);
            }
        }
    }
}

实体类

/**
 * 注解使用
 * @author lizhonghao
 */
@Setter
@Getter
public class DrinkVo {

    private String appleName;

    @Drinks(categoryType = Drinks.Category.SOFT_DRINK)
    private String appleColor;

    @DrinkProvider(id = 1, name = "", address = "")
    private String appleProvider;

}

应用初始化时加载

public class Main {

    /**
     * 注:后序会实现哪些类使用这个注解的功能
     */
    public static void main(String[] args) {
        DrinksImpl.drinkInfo(DrinkVo.class);
    }
}

三、. 创建自定义注解 – 之动态运行时注解。

import javax.validation.Constraint;
import javax.validation.Payload;
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 lizhonghao
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.FIELD)
@Constraint(validatedBy = ValidIDImpl.class)
public @interface ValidID {

    String message();
    Class[] groups() default { };
    Class[] payload() default { };
}

注解的实现类

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class ValidIDImpl implements ConstraintValidator {

    private static final String IDPattern = "^[0-9a-zA-Z]$";

    @Override
    public void initialize(ValidID constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value instanceof String) {
            return ((String) value).matches(IDPattern);
        }
        return false;
    }
}

实体类

import lombok.Data;

/**
 * @author lizhonghao
 */
@Data
public class ValidVO {

    @ValidID(message = "不规范ID")
    private String id;
    
}

测试类 (注意:必须要有@Valid 注解,否则不会校验)

    @PostMapping(value = "validid")
    public String testValid(@RequestBody @Valid ValidVO payload){
 
        return JSON.toJSONString(payload);
    }

你可能感兴趣的:(Java基础知识,java)