引入高级系统架构师JohnGao的一个开源成果------MiniBean
MiniBean的基本使用方式
1、使用MiniBean来构建自动赋值应用场景
在开始在你的代码中使用MinBean之前,我们首先应该下载MiniBean所需的构件。值得庆幸的是,MiniBean并没有依赖除了Java API之外的其他构件,也就是说使用MiniBean你将完全不必下载其他的第三方构件。MiniBean目前的最新版本是2.0.1,该版本目前较为稳定,单元测试覆盖率已经达到85%以上,完全可以满足RC版本的要求。 当成功下载好MiniBean的主要构件后,我们需要将它引入至项目中。然后我们接下来看看如何在程序中使用MiniBean来实现Beans属性元素之间的自动赋值。我们首先应该预先定义好2个Bean(分别为目标对象与源对象)。
定义源对象Bean:
publicclassTestBeanA{ privateint id; privateString name =null; privateString pwd =null; /* 此处省略set和get方法 */}
定义目标对象Bean:
@AssignmentpublicclassTestBeanB{ @Paramater privateint id; @Paramater privateString name; @Paramater privateString pwd; /* 此处省略set和get方法 */}
当成功定义好目标对象Bean与源对象Bean以后,我们首先来看看目标对象的类型的上方,标记了一个注解叫做@Assignment。该注解用于标记目标对象Bean,其作用域为类型,只有标记了该注解的Bean才能实现后续的自动赋值操作。而@Paramater注解则用于标记在赋值过程中需要被源对象赋值的目标对象中的指定字段,只有在字段的上方标记有@Paramater注解时,MiniBean才会对其进行赋值注入。@Paramater除了允许标记在字段上,还允许标记在方法上,也就是说@Paramater注解的作用域是字段与方法。
接下来我们使用MiniBean提供的BeanContext组件实现Beans之间的自动赋值操作:
@Testpublicvoid test1(){ TestBeanA sourceObject =newTestBeanA(); sourceObject.setId(1); sourceObject.setName("JohnGao"); sourceObject.setPwd("123456"); TestBeanB goalObject =newTestBeanB(); /* 实现自动赋值操作 */ BeanContext.setParam(goalObject, sourceObject); /* 单元测试预期值与实际值是否匹配 */ Assert.assertEquals(goalObject.getId(), sourceObject.getId()); Assert.assertEquals(goalObject.getName(), sourceObject.getName()); Assert.assertEquals(goalObject.getPwd(), sourceObject.getPwd());}
上述程序示例我们可以看出,BeanContext类型是作为整个Beans赋值操作的入口容器,由该类型负责将目标对象与实际对象之间数据进行共享牵引。该方法对外包含一个公共方法setParam(goalObject, sourceObject),该方法的第一个参数用于传递目标对象,而后一个用于传递源对象。所以大家在使用时一定要注意参数传递的顺序,切勿将顺序反转,以免发生一些不必要的错误。
2、使用@Paramater定义目标对象字段的备用名称与备用名称组
在实际的开发过程中,我们不可能要求Beans均保持相同的字段名称,因为这需要根据实际的业务需求而定。所以MiniBean考虑到了这一点,为开发人员提供有字段的备用及备用名称组功能供其使用。如果我们需要在目标对象的字段定义备用名称,则需要使用@Paramater注解的value、name或names属性。value属性用于定义目标对象字段的备用名称,而name属性同样也用于备用名称定义,只不过value属性是缺省的,而name属性则是显式定义的,除此之外没有其他区别。也就是说在程序中如果显示定义有name属性则重写value属性的定义。而names属性则用于定义字段的备用名称组,也就是说一个字段可以拥有N个备用名称,在运行时,MiniBean会根据源对象字段的名称匹配备用名称组中对应的名称。
定义目标对象字段的备用名称:
@AssignmentpublicclassTestBeanD{ @Paramater("id") privateint userId; @Paramater(name ="name") privateString userName; @Paramater(names ={"pwd","pwd2","pwd3"}) privateString passWord; /* 此处省略set和get方法 */}
从上述程序示例中,我们使用了@Paramater中包含的3种有效属性来定义目标对象字段的备用名称和备用名称组。值得注意的是,value属性和name属性的类型都是String类型,只有names属性是String类型,所以大家在定义属性名称的时候一定要注意。
3、使用@AutoParameters实现目标对象所有字段的赋值注入
任何事情都没有万一的,如果Beans之间的字段名称都是相同的时候,还采取@Paramater的方式进行定义则显得过于繁琐。所以MiniBean提供有@AutoParameters注解用于标记目标对象中所有的字段都允许被源对象赋值注入。@AutoParameters注解的作用域仅限于类型,所以千万不要将该注解标记与字段或者方法上,否则编译时将会出现错误。并且一旦在程序中使用了@AutoParameters注解,我们完全可以去除掉字段上的@Paramater注解,当然@Paramater和@AutoParameters注解也可以混合使用,以此满足一些特定的应用场景。
使用@AutoParameters和@Paramater混合字段注入:
@Assignment@AutoParameterspublicclassTestBeanF{ privateint id; @Paramater("name") privateString userName; @Paramater(names ={"pwd1","pwd2","pw3"}) privateString passWord; /* 此处省略set和get方法 */}
在@AutoParameters注解内部,定义有一个缺省的value属性。该属性缺省值为“true”,也就是说@AutoParameters可以生效,一旦value属性为“false”的时候,@AutoParameters则失效。一点@AutoParameters失效后,目标对象中如果没有标记@Paramater的字段MiniBean将不再为其提供赋值注入。
@AutoParameters失效:
@AutoParameters(false)
4、使用ignore属性定义字段名称的大小写兼容
或许在某些应用环境下,我们往往要考虑相同的字段名称,但大小写却不一致的情况下的自动赋值操作。Java是一门强类型的语言,不仅仅会检查类型的兼容,同样变量名称的大小写也是区分的。所以这个时候,如果使用MiniBean进行Bean之间的自动赋值操作,我们就需要考虑有什么办法可以做到相同的字段名,但大小写不一致的情况,仍然能够实现自动赋值操作。MiniBean在@Paramater和@AutoParameters注解内部提供有ignore属性供开发人员选择,该属性的作用就是用于定义是否兼容字段的大小写,缺省情况下ignore的值为“false”,即不开启大小写兼容,反之则为开启。
使用ignore属性开启字段名称的大小写兼容:
@Assignment@AutoParameters(ignore =true)publicclassTestBeanK{ privateintId; @Paramater privateString name; @Paramater(ignore =true) privateStringPwd; /* 此处省略set和get方法 */}
5、一对多的自动赋值操作
在前面几个章节中,我们更多演示的是如果使用MiniBean进行目标对象和源对象之间的一对一自动赋值操作。那么如果我们有多个目标对象都需要与源对象之间进行自动赋值操作的时候,MiniBean是否提供有良好的支持呢?值得庆幸的是MiniBean提供有高效、便捷的一对多赋值策略实现一个源对象与多个目标对象之间的自动赋值操作。 我们可以使用BeanContext抽象类的setParams(Set goalObjects, K sourceObjects)方法实现一对多的自动赋值操作。和setParam方法不同的是,setParams方法的第一个参数为目标对象集合,也就是说开发人员只需要将需要实现自动赋值的目标对象集合存储进一个Set列表中即可完成一对多的自动赋值操作。
使用一对多的赋值策略:
@Testpublicvoid test11(){ TestBeanA sourceObject =newTestBeanA(); sourceObject.setId(1); sourceObject.setName("JohnGao"); sourceObject.setPwd("123456"); Set goalObjects =newHashSet(); TestBeanK testBeanK =newTestBeanK(); TestBeanL testBeanL =newTestBeanL(); goalObjects.add(newTestBeanK); goalObjects.add(newTestBeanL); BeanContext.setParams(goalObjects, sourceObject); }