java 自定义注解

1、注解

1.1 注解的定义

Java文件叫做Annotation,用@interface表示。

1.2 注解分类

注解大体上分为三种:标记注解,一般注解,元注解。

1.2.1 标记注解

@Override用于标识,该方法是继承自超类的。这样,当超类的方法修改后,实现类就可以直接看到了。

@Deprecated注解,则是标识当前方法或者类已经不推荐使用,如果用户还是要使用,会生成编译的警告。

@SuppressWarnings,抑制编译器发出特定警告。

1.2.2 一般注解

@Generated,标识计算机产生的源代码。

1.2.3 元注解

  • @Documented 标记生成javadoc
  • @Inherited 标记继承关系
  • @Retention 注解的生存期
  • @Target 标注的目标    

1.3 注解的保留策略

  • @Retention(RetentionPolicy.SOURCE)   // 注解仅存在于源码中,在class字节码文件中不包含。
  • @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。
  • @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到。

1.4 作用目标

  • @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)         // 包

2、java示例

2.1 自定义注解

/**
 * 赋值
 * @Title: Assign.java
 * @Package com.spring.pro.annotation
 * @Description:
 * @author ybwei
 * @date 2018年11月15日 下午4:55:51
 * @version V1.0
 */
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Assign {
	public String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Title: Validate.java
 * @Package com.spring.pro.annotation
 * @Description:校验
 * @author ybwei
 * @date 2018年11月15日 下午1:57:02
 * @version V1.0
 */
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
	/**
	 * 最小值
	 * @return
	 * @author ybwei
	 */
	public int min() default 1;

	/**
	 * 最大值
	 * @return
	 * @author ybwei
	 */
	public int max() default 10;
}

2.2 定义使用注解实体

import com.spring.pro.annotation.Assign;
import com.spring.pro.annotation.Validate;

/**
 * @Title: User.java
 * @Package com.spring.pro.model
 * @Description:
 * @author ybwei
 * @date 2018年11月15日 下午3:49:28
 * @version V1.0
 */
public class Person {
	@Assign(value = "张三")
	private String name;
	private String gender;
	@Validate(min = 22, max = 50)
	private Integer age;

	public Person() {
		super();
	}

	public Person(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	@Assign(value = "男")
	public void setGender(String gender) {
		this.gender = gender;
	}

}

2.3 注解解析器

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.spring.pro.annotation.Assign;

/**
 * @Title: ObjectFactory.java
 * @Package com.spring.pro.factory
 * @Description:
 * @author ybwei
 * @date 2018年11月15日 下午3:45:01
 * @version V1.0
 */
public class ObjectFactory {
	public static <T> T create(Class<T> clazz) throws Exception {
		T obj = clazz.getConstructor(new Class[] {}).newInstance(new Object[] {});
		// 获取T类中所有的方法(getDeclaredMethods也行)
		Method[] methods = clazz.getMethods();
		// 获取T类的所有属性(如果使用getFields,就无法获取到private的属性)
		Field[] fields = clazz.getDeclaredFields();
		for (Method method : methods) {
			// 如果此方法有注解,就把注解里面的数据赋值到obj对象
			if (method.isAnnotationPresent(Assign.class)) {
				Assign assign = method.getAnnotation(Assign.class);
				method.invoke(obj, assign.value());
			}
		}
		for (Field field : fields) {
			if (field.isAnnotationPresent(Assign.class)) {
				Assign assign = field.getAnnotation(Assign.class);
				field.setAccessible(true);
				field.set(obj, assign.value());
			}
		}
		return obj;
	}
}
import java.lang.reflect.Field;

import com.spring.pro.annotation.Validate;

/**
 * @Title: ObjectValidate.java
 * @Package com.spring.pro.factory
 * @Description:
 * @author ybwei
 * @date 2018年11月15日 下午3:52:48
 * @version V1.0
 */
public class ObjectValidate {
	public static <T> boolean validate(T obj) throws Exception {
		// 获取T类的所有属性(如果使用getFields,就无法获取到private的属性)
		Field[] fields = obj.getClass().getDeclaredFields();

		for (Field field : fields) {
			// 如果属性有注解,就进行校验
			if (field.isAnnotationPresent(Validate.class)) {
				Validate validate = field.getAnnotation(Validate.class);
				field.setAccessible(true);
				Integer num = (Integer) field.get(obj);
				if (num < validate.min()) {
					System.out.println(field.getName() + "小于最小长度!!");
					return false;
				}
				if (num > validate.max()) {
					System.out.println(field.getName() + "大于最小长度!!");
					return false;
				}
			}
		}
		return true;
	}
}

2.4 测试

@Test
public void testObjectAssign() throws Exception {
	Person person = ObjectFactory.create(Person.class);

	System.out.println(person.getName());
	System.out.println(person.getGender());
}

@Test
public void testObjectValidate() throws Exception {
	Person person = new Person("李四",21);
	System.out.println(ObjectValidate.validate(person));
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值