最近学习注解,于是实现一个kotlin版本的加载配置项注解。
注解代码 :
/**
* property annotate
* use those to easy use property
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class PropertyBase(val filePath: String)
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class IntProperty(val propertyName: String, val defValue: Int)
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class DoubleProperty(val propertyName: String, val defValue: Double)
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class StringProperty(val propertyName: String, val defValue: String)
注解处理器 :
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.lang.Exception
import java.util.*
class PropertyUtil {
companion object {
fun loadProperty(obj: Any) {
if(!obj.javaClass.isAnnotationPresent(PropertyBase::class.java)) {
throw Exception("$obj have no annotation for property")
}
val pp = Properties().apply {
val pb = obj.javaClass.getAnnotation(PropertyBase::class.java)
load(BufferedInputStream(FileInputStream(pb.filePath)))
}
obj.javaClass.declaredFields.forEach {
when {
it.isAnnotationPresent(IntProperty::class.java) -> {
it.getAnnotation(IntProperty::class.java).let { ia ->
it.isAccessible = true
it.setInt(obj, pp.getProperty(ia.propertyName)?.toInt() ?: ia.defValue)
}
}
it.isAnnotationPresent(DoubleProperty::class.java) -> {
it.getAnnotation(DoubleProperty::class.java).let { da ->
it.isAccessible = true
it.setDouble(obj, pp.getProperty(da.propertyName)?.toDouble() ?: da.defValue)
}
}
it.isAnnotationPresent(StringProperty::class.java) -> {
it.getAnnotation(StringProperty::class.java).let { sa ->
it.isAccessible = true
it.set(obj, pp.getProperty(sa.propertyName) ?: sa.defValue)
}
}
}
}
}
}
}
单元测试类 :
import twsLib.util.propertAnnotate.DoubleProperty
import twsLib.util.propertAnnotate.IntProperty
import twsLib.util.propertAnnotate.PropertyBase
import twsLib.util.propertAnnotate.StringProperty
@PropertyBase("src/test/resources/test.properties")
class TestProperty {
@IntProperty("test.intProp", 1)
var intProp = 1
@DoubleProperty("test.doubleProp", 2.toDouble())
var doubleProp = 2.toDouble()
@StringProperty("test.stringProp", "def")
var stringProp = "def"
}
JUnit4单元测试代码 :
import org.junit.Assert
import org.junit.Test
import twsLib.util.propertAnnotate.PropertyUtil
class PropertyUtilTest {
@Test
fun testProp() {
val tp = TestProperty()
PropertyUtil.loadProperty(tp)
Assert.assertEquals(2, tp.intProp)
Assert.assertEquals(3.14, tp.doubleProp, 0.0001)
Assert.assertEquals("pi", tp.stringProp)
}
}
最后,测试用配置文件(test.properties):
test.intProp = 2
test.doubleProp = 3.14
test.stringProp = pi
单元测试通过 :