做一些分享吧,我今天将部分写好的工具类以及一些工具包做一些分享。之前一直想开源来着,工作忙起来就忘了,部分代码使用系统不一定适合大家使用,可以自行修改。
下面说一下相关的几个项目所包含的内容以及依赖关系(使用maven做开发管理工具)
aurora.util 看到util也明白了,基于common.lang3等做的扩展,后续我会往里面继续加东西。
pulse.reflex Java反射的封装包,提供了反射内容的缓存,提供并发支持。操作java反射是很繁琐也很痛苦的,特别是一些异常的处理,整个包不但对反射的内容做了缓存,同时还精简了代码的编写。
pulse.expression 主要为映射提供表达式支持的包。
pulse.map 主要提供对象的配置式赋值功能。一般我们做开发的过程中会有对象之间复制内容的场景,特别是层次较深的对象到一个层次不那么深的对象上时就成了一件很痛苦的事,该包提供了这个功能,同时可以进行对应的配置,还提供了一些简单的数据转换的支持。
pulse.map -> pulse.expression -> pulse.reflex -> aurora.util
——————————————————————————————————————————————————————————————————————————————
下面将展示一些使用的实例,具体的代码能够在单元测试包里找到。(个人做的单元测试覆盖率不是特别高,需要用来做项目的同学可以增强覆盖率)
aurora.util
net.juancai.aurora.io.quiet.Quiet 静默操作文件的入口,通过该类型中的静态方法能够对文件实现快速的写入和读取。
net.juancai.aurora.lang.AnyMap 语言级别的扩展,该数据结构实现了一对多的Map,一个Key可以装多个Value。
剩下的就是一些基础的数据操作的静态方法,有一些比较有趣的东东,各位自性发掘。
pulse.expression
具体使用方法如下。表达式支持get方法以及直接读写字段。说说功能吧,支持getXXX()方法的匹配,支持字段各种约束的抓取,灰常方便哦。
不过整体一来pulse.reflex包,都通过该包来实现反射API的缓存,嘿嘿。性能提供也可以通过该方法。
package net.juancai.pulse.expression;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import net.juancai.pulse.expression.Expression;
import net.juancai.pulse.expression.RunExpressionExcetion;
import org.junit.Test;
public class ExpressionTestCase {
@Test
public void mixed() {
/// mixed test case
Expression expr = new ExpressionDefault("a.b.c().d");
assertTrue(expr.get(new Mixed()).equals("this is 'd' in C object"));
}
@Test
public void rootMethod(){
Expression expr = new ExpressionDefault("a()");
assertTrue( expr.get(new RootMethod()).equals("this is a() in RootMethod") );
}
@Test
public void fieldNotFound(){
/// field not found test case
Expression expr = new ExpressionDefault("a.e");
try {
expr.get(new Mixed());
fail();
} catch (RunExpressionExcetion e) {
}
}
@Test
public void methodNotFound(){
/// method not found test case
Expression expr = new ExpressionDefault("a.e()");
try {
expr.get(new Mixed());
fail();
} catch (RunExpressionExcetion e) {
}
}
@Test
public void nullOnPath() {
/// null in path expression test case
Expression expr = new ExpressionDefault("a.b.c");
assertTrue( expr.get( new NullOnPath() ) == null );
}
@Test
public void nullOnRoot() {
/// null in path expression test case
Expression expr = new ExpressionDefault("a.b.c");
assertTrue( expr.get( null ) == null );
}
public static class RootMethod {
String a() {
return "this is a() in RootMethod";
}
}
public static class NullOnPath {
A a = new A();
public static class A {
B b;
}
public static class B {
}
}
public static class Mixed {
A a = new A();
public static class A {
B b = new B();
}
public static class B {
C c() {
return new C();
}
}
public static class C {
String d = "this is 'd' in C object";
}
}
}
pulse.map
有一些比较有趣的是映射比较好玩,在处理DDD设计时会经常用到相关的对象转换,该工具类会帮你节省大量代码量。性能。。。别考虑了10倍差距,毕竟还有转换和反射的时间。采用的是字段的赋值方式,所以不会很快。
有高手可以帮忙支招一下,是否有字段的更高效的方法。下面列举额一下包实现的功能。
1. 集合接口支持,当目标对象提供了接口时,框架会帮助你生成对应的结果。(包含Collection/Set,方便扩展,装饰模式)
2. 提供数组的直接转换,非常完美的支持泛型的抓取。
3. 自定义对象转换,同时能够区分java自带对象的直接映射。
package net.juancai.pulse.map.test;
import static org.junit.Assert.assertTrue;
import net.juancai.pulse.map.BeanMappingDefault;
import net.juancai.pulse.map.ClassMapping;
import net.juancai.pulse.map.FieldMapping;
import org.junit.Test;
public class MixedTestCase {
private static int count = 0;
@Test
public void test() {
BeanMappingDefault mapping = new BeanMappingDefault();
Src src = new Src();
Tgt tgt = mapping.target(Tgt.class, src);
assertTrue(tgt.name.equals("src -> 0"));
}
public static class Src {
String str() {
return "src -> " + (count++);
}
}
@ClassMapping
public static class Tgt {
@FieldMapping(expression = "str()")
String name;
}
}
pulse.reflex
好吧,反射就演示一下字段的读写,这部分我用的比较多。事实上内部实现都采用反射,所以也别指望其性能能有多么牛逼。考虑过用asm之类的东东,但是确实字段没法处理。
我也要自夸一下, 全局的缓存带来的性能提升还是比较可观的,链式的API让你的编写也变得更加容易。
另外对于方法还提供的默认定位,例如有方法test带有参数,如果通过java的默认反射api需要传入参数类型才能定位,如果用这个API就可以更加容易的拿到.下面列举一下所实现的功能吧。
1. 简化API名称,对于反射原有的名称做了简化。
2. 增强反射缓存,不会每次调用都从Class对象抓取。
3. 增强泛型API,实现对泛型的强化支持,快速抓取相关参数。
4. 静默API,不会有强制的Exception抛出,内部全部转化为RuntimeException。有些缺陷就是需要外部自行捕获。
5. 链式调用API,简化调用链的书写,one-line Code成为可能。
package net.juancai.pulse.reflex.test.action;
import static org.junit.Assert.assertTrue;
import net.juancai.pulse.reflex.Defines;
import net.juancai.pulse.reflex.FieldDefine;
import net.juancai.pulse.reflex.TypeDefine;
import org.junit.Test;
public class FieldActionTestCase {
@Test
public void testAction() {
TypeDefine type = Defines.get(TestClass1.class);
TestClass1 tc1 = new TestClass1();
FieldDefine nfd = type.getField("name");
nfd.getAction().set(tc1, "this is tc1");
assertTrue(nfd.getAction().get(tc1).equals("this is tc1"));
}
public static class TestClass1 extends SuperTestClass1 {
String name;
}
public static class SuperTestClass1 {
Integer int1;
}
}
末尾跟上我的文件地址( 优快云下载)