自定义注解类和使用

元注解

元注解是用于修饰注解的注解,一般用于指定某个注解生命周期以及作用目标等信息。

@Target:注解的作用目标

ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
ElementType.FIELD:允许作用在属性字段上
ElementType.METHOD:允许作用在方法上
ElementType.PARAMETER:允许作用在方法参数上
ElementType.CONSTRUCTOR:允许作用在构造器上
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
ElementType.ANNOTATION_TYPE:允许作用在注解上
ElementType.PACKAGE:允许作用在包上

@Retention:注解的生命周期

RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
RetentionPolicy.RUNTIME:永久保存,可以反射获取

@Documented:注解是否应当被包含在 JavaDoc 文档中

当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃。

@Inherited:是否允许子类继承该注解

我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解。

JAVA 的内置三大注解

@Override

它没有任何的属性,所以并不能存储任何其他信息。它只能作用于方法之上,编译结束后将被丢弃。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

@Deprecated

@SuppressWarnings

自定义注解类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoTableName {
	String value() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoFieldColumn {
	String value() default "";
}

使用注解类

@AnnoTableName("T_STUDENT")
public class AnnoStudent {
	@AnnoFieldColumn("NAME")
	private String name;
	
	@AnnoFieldColumn("POST_ADDRESS")
	private String postAddress;

	private Integer gender;
	...省略get set
}
public class Demo01 {
	@Test
	public void test01() {
		AnnoStudent annoStudent = new AnnoStudent();
		annoStudent.setName("小明");
		annoStudent.setPostAddress("wu");
		String selectSql = getSelectSql(annoStudent);
		System.err.println(selectSql);
		// select NAME, POST_ADDRESS from T_STUDENT where 1=1 and NAME=小明 and POST_ADDRESS=wu
	}
	public static String getSelectSql(AnnoStudent annoStudent) {
		Class<? extends AnnoStudent> clazz = annoStudent.getClass();
		AnnoTableName annotationTable = clazz.getAnnotation(AnnoTableName.class);
		if (annotationTable == null) {
			throw new RuntimeException("参数有错!");
		}
		Field[] fieldArr = clazz.getDeclaredFields();
		String columnPart = "";
		String wherePart = " where 1=1";
		for (int i = 0; i < fieldArr.length; i++) {
			Field field = fieldArr[i];
			AnnoFieldColumn annotationField = field.getAnnotation(AnnoFieldColumn.class);
			if (annotationField == null) {
				continue;
			}
			String valueField = annotationField.value();
			if (i == 0) {
				columnPart += valueField;
			} else {
				columnPart += ", " + valueField;
			}
			try {
				field.setAccessible(true);
				Object object = field.get(annoStudent);
				if (object != null) {
					wherePart += " and " + valueField + "=" + object;
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		StringBuffer sb = new StringBuffer();
		sb.append("select ");
		String valueTable = annotationTable.value();
		sb.append(columnPart + " from " + valueTable + wherePart);
		return sb.toString();
	}
}

结合spring使用注解类

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface Strategy {
	String[] names();
}
@Strategy(names="messageStrategyDefault")
@Component
public class MessageStrategyDefault {}
/**
 *
 * 寻找使用 @Strategy 注解 的类,并打印相关信息
 *
 */
@Component
public class StrategyExplain implements ApplicationListener<ContextRefreshedEvent> {

	private String annotationName = Strategy.class.getName();

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		ApplicationContext applicationContext = event.getApplicationContext();
		_initial(applicationContext);
	}

	private void _initial(ApplicationContext applicationContext) {
		if (!(applicationContext instanceof BeanDefinitionRegistry)) {
			throw new RuntimeException("applicationContext is not instanceof BeanDefinitionRegistry");
		}

		List<AnnotatedBeanDefinition> beanDefinitionList = _getAnnotationBeanDefinition(applicationContext, applicationContext.getBeanDefinitionNames(), annotationName);
		beanDefinitionList.forEach(item->{
			Map<String, Object> annotationAttributes = item.getMetadata().getAnnotationAttributes(annotationName);
			String[] names = (String[])annotationAttributes.get("names");
			String tip = String.format("%s annotationName[name]=%s", item.getBeanClassName(), names[0]);
			System.err.println(tip);
		});
	}

	private List<AnnotatedBeanDefinition> _getAnnotationBeanDefinition(ApplicationContext applicationContext, String[] beanDefinitionNames, String annotationName) {
		List<AnnotatedBeanDefinition> beanDefinitionList = new ArrayList<>();
		for(String beanDefinitionName: beanDefinitionNames) {
			BeanDefinition beanDefinition = ((BeanDefinitionRegistry) applicationContext).getBeanDefinition(beanDefinitionName);
			if (!(beanDefinition instanceof AnnotatedBeanDefinition)) {
				continue;
			}
			AnnotationMetadata metadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata();
			if(metadata.hasAnnotation(annotationName)) {
				beanDefinitionList.add((AnnotatedBeanDefinition) beanDefinition);
			}
		}
		return beanDefinitionList;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_26264237

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值