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 -是否允许子类继承该注解
分类二: 第三方框架
分类三:自定义注解:
一、自定义注解类编写规则:
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);
}