java:从spring-core移植的注解(annotation)扫描工具模组common-annotutils(适用JDK 1.7)

AnnotationUtils

spring-core的部件组装基本原理是基于注解(annotation),通过扫描类、方法、成员上定义的注解来决定组装逻辑。

spring-core将注解扫描框架封装为一个工具类:org.springframework.core.annotation.AnnotationUtils,使用这个工具类就可以从一个复杂类型或方法中获取指定的注解信息,大概就是这样:

java 复制代码
	AppConstantType annot = AnnotationUtils.findAnnotation(ClassB.class,AppConstantType.class);
	SyStem.out.printf("%s\n",annot);

这个注解扫描框架对于希望建立以注解组装机制的应用就很有用。但它是深度集成在spring-core代码中的。如果希望不依赖spring框架使用这个工具,只能自己想办法将org.springframework.core.annotation包下的代码抽取出来使用,而我的项目需要在JDK 1.7环境下使用,我现在现在使用的spring-core 5.x版本最低要求JDK 1.8。

所以org.springframework.core.annotation包下的代码大量使用了JDK 1.8的新特性:lamda表达、steam等。

所以对于我来说不仅要把org.springframework.core.annotation包下的代码抽取出来,还要对代码进行大量的重构,以适应JDK 1.7 版本。

花了差不多一周时间,总算完成了移植工作,为了验证代码重构的正确性,我同时还将org.springframework.core.annotation包对应的单元测试代码(spring-core/src/test/java/org/springframework/core/annotation)也同步移植出来。最终跑通了所有的单元测试。

common-annotutils

为了方便使用,我将移植出来的spring-core将注解扫描框架封装为jar包并发布到maven中央仓库。

依赖引用方式如下:

maven:

xml 复制代码
		<dependency>
			<groupId>com.gitee.l0km</groupId>
			<artifactId>common-annotutils</artifactId>
			<version>2.9.0</version>
		</dependency>

gradle:

implementation group: 'com.gitee.l0km', name: 'common-annotutils', version: '2.9.0'

调用示例

java 复制代码
import static org.junit.Assert.*;

import java.lang.reflect.Method;

import static net.gdface.utils.SimpleLog.log;

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.gitee.l0km.common.annotations.AppConstantField;
import com.gitee.l0km.common.annotations.AppConstantType;
import com.gitee.l0km.common.annotations.CellLogTag;
import com.gitee.l0km.common.annotations.TestLogTag;
import com.google.common.collect.Multimap;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AnnotationTest {

	@Test
	public void test2AnnotationUtils() {
		try {
			{
				AppConstantType annot = AnnotationUtils.findAnnotation(ClassB.class,AppConstantType.class);
				log("{}",annot);
			}
			{
				AppConstantType annot = AnnotationUtils.findAnnotation(In2.class,AppConstantType.class);
				log("{}",annot);
			}
			{
				AppConstantField annot = AnnotationUtils.findAnnotation(ClassB.class.getMethod("m0"),AppConstantField.class);
				log("{}",annot);
			}
				
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}
	@Test
	public void test3GetAnnotation() {
		try {
			{
				Method method = ClassB.class.getMethod("m0");
				TestLogTag annot = AnnotationUtils.findAnnotation(method,TestLogTag.class);
				log("{}",annot);
				CellLogTag cellLogTag= AnnotationUtils.getAnnotation(annot, CellLogTag.class);
				log("{}",cellLogTag);
			}
				
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}
	@Test
	public void test4GetAllAnnotationAttributes() {
		try {
			{
				Method method = ClassA.class.getMethod("m0");
				Multimap<String, Object> attrs = AnnotatedElementUtils.getAllAnnotationAttributes(method,TestLogTag.class.getName());
				log("{}",attrs);
			}
			{
				Method method = ClassB.class.getMethod("m0");
				Multimap<String, Object> attrs = AnnotatedElementUtils.getAllAnnotationAttributes(method,TestLogTag.class.getName());
				log("{}",attrs);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}
	@AppConstantType
	public static class ClassA {
		@AppConstantField
		@TestLogTag(TestEamLogTag.DT_ADD_LOG)
		public void m0() {};
	}
	public static class ClassB extends ClassA {
		@Override
		@TestLogTag(value=TestEamLogTag.DT_ADD_DEV,tag="hello")
		public void m0() {};
		
	}
	@AppConstantType
	public static interface In1{}
	public static interface In2 extends In1{}
	public static class ClassC implements In1{}

}

完整代码

完整代码参见码云仓库:
https://gitee.com/l0km/common-java/tree/master/common-annotutils

单元测试代码位置:
https://gitee.com/l0km/common-java/tree/master/common-annotutils-test

相关推荐
原野心存几秒前
java基础进阶知识点汇总(1)
java·开发语言
无理 Java32 分钟前
【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
java·后端·spring·面试·mvc·框架·springmvc
gobeyye1 小时前
spring loC&DI 详解
java·spring·rpc
鱼跃鹰飞1 小时前
Leecode热题100-295.数据流中的中位数
java·服务器·开发语言·前端·算法·leetcode·面试
我是浮夸1 小时前
MyBatisPlus——学习笔记
java·spring boot·mybatis
TANGLONG2221 小时前
【C语言】数据在内存中的存储(万字解析)
java·c语言·c++·python·考研·面试·蓝桥杯
杨荧1 小时前
【JAVA开源】基于Vue和SpringBoot的水果购物网站
java·开发语言·vue.js·spring boot·spring cloud·开源
Leighteen2 小时前
ThreadLocal内存泄漏分析
java
java6666688882 小时前
Java中的对象生命周期管理:从Spring Bean到JVM对象的深度解析
java·jvm·spring
柚乐果果2 小时前
数据分析实战简例
java·大数据·python