在编写程序的时候,总是不可避免的需要使用一些常量,甚至很多的常量。我们可以对常量进行一个很简单的分类:
记忆性常量:主要出于程序结构上的考虑而设定的常量。譬如为了避免一个没有字面意思的魔法数,或者避免拼写容易出错,或者不容记住的内容。
业务性常量:表示一个业务上的一个特定业务实体的属性或属性值。
很多的时候,一个业务性常量很多时候也是一个记忆性常量。
在一个大型项目中,参与的人员和代码数量通常都会比较多,没有好的管理策略,常量的使用往往想入混乱中。譬如重复定义,其维护的值甚至还不一致,以外覆盖;譬如仅仅为了使用某个常量,而引入某个包或者类,由此可能引出模块间的循环依赖等。
良好的设计结构,以及严格的开发纪律基本上可以解决上述问题。除了有时的确是不可避免的出现以上问题外,有时一些所谓的业务常量只有在部署期间或同别的系统集成是才能获得。所以有必要进一步的探讨常量的管理手段。
记得在JavaEye上看到一篇关于Spring属性注入的文章,灵机一动,不是恰好可以用来处理这个问题吗?所谓属性注入,意思是指将配置信息写在Properties文件中,通过IOC容器透明的注入。
这么设想下,如果常量最终都可以用配置文件配置,那么就可以解决“业务常量只有在部署期间或同别的系统集成是才能获得”的问题,如果同时还可以透明的宣称使用常量,那么几乎所有的问题就完美了:
不害怕重复定义错误
消除有常量引用引起的循环引用
提供从部署期覆盖编译期的灵活性
使用Spring的扩展名称空间和Java5的Annotation语法,我们可以整理出以以下思路
定义一个Annotation类
实现一个Annotation的Processor
配置Processor Bean
实现过程大致如下:
一、Annotation
@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Properties {
String name() default "";
String value() default "";
String namePrefix() default "";
String namePostfix() default "";
}
二、Processor
public class AnnotationPropertiesBeanPostProcessor extends PropertyPlaceholderConfigurer implements BeanPostProcessor, InitializingBean {
private java.util.Properties pros;
private String namePrefix = "";
private String namePostfix = "";
public void setEnabledClassList(Class[] enabledClassList) {
this.enabledClassList = enabledClassList;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
HandlePropertiesAnnotatedBean(bean, bean.getClass());
return bean;
}
private void HandlePropertiesAnnotatedBean(Object bean, Class<?> asClass) throws SecurityException {
if( isHandleInheritance(asClass.getSuperclass()) ){
HandlePropertiesAnnotatedBean(bean, asClass.getSuperclass());
}
Field[] fields = asClass.getDeclaredFields();
for (Field field : fields) {
if (support(field.getType())) {
handleField(bean, field, defaultIsRequired(bean, asClass));
}
}
}
private void handleField(Object bean, Field field, boolean defaultIsRequired) {
if (isProhibited(field)) {
return;
}
if (defaultIsRequired || isRequired(field)) {
try {
ReflectionUtils.makeAccessible(field);
field.set(bean, getPropertyValue(field));
} catch (Exception ex) {
Logger.getLogger(AnnotationPropertiesBeanPostProcessor.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
......
三、配置 bean
<bean class="com.joyplus.ext.spring.AnnotationPropertiesBeanPostProcessor" />
四、使用实例
@Properties(namePrefix="ddd")
public class Config {
@Properties(name="author")
private String author;
private String tvalue;
@Properties(value="default name",namePrefix="ooo")
private String tname;
private String nonValue;
// getter and setter
}
五、示例Properties文件内容
dddauthor=用的是 class 级别的 prefix
oootname=用的是 field 级别的 prefix
dddnonValue=用sd
分享到:
相关推荐
答:JDBC数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问。 什么情况下不建议使用Hibernate? 答:当数据量大,并且表关系复杂的时候不建议使用。 sleep()和wait()有什么区别? ...
二、java基础知识点对于学习Java全栈的重要性随着互联网技术的发展,Java已经成为企业编程领域常用的一种编程语言,现在Java已经广泛应用于各行各业,可以说它无处不在,熟练掌握Java知识点,势必可以打开大量的职业...
第一章:Java开始 1 学习目标 1 Java历史 2 Java技术概述 3 Java技术的优点 3 Java虚拟机 4 类加载器 6 Windows环境变量 8 内容总结 13 独立实践 14 第二章: 面向对象概述 15 学习目标 15 面向对象(Object Oriented...
有一个常量MANAGEERPOWER数值为管理员权限。做项目时自行设置。(修改“=”后的值就可以) |___HyberbinServlet.java封装了Servlet,以后写的sevlet直接继承这个类就可以。里面有一个抽象类execute,在继承的类中...
Iterator [java] 迭代器, 迭代程序 legal 合法的 ['li:gәl] log n.日志,记录 [lɒg] native (关键字) ?? ['neitiv] nested [java] 嵌套的 ['nestid] '如:内部类(nested classes) Object [java] 对象 ['ɒbdʒ...
【基础】Java 中定义常量的几种方法 25 【基础】什么时候使用字节流?什么时候用字符流? 26 【基础】GBK与UTF-8的区别 26 【基础】static、final、const的区别 26 final: 26 static: 27 【基础】如何实现对象克隆?...
如果您不喜欢用SpringBoot,或者您是一个spring初学者,您可以切换到Guns V1.0(点击这里)分支, Guns V1.0基于spring的java bean方式配置项目,同样简洁易上手. 注:SpringBoot强大的Auto Config和统一的依赖管理极大的...
本系统是基于RBAC授权和基于用户授权的细粒度权限控制通用平台,并提供单点登录、会话管理和日志管理。接入的系统可自由定义组织、角色、权限、资源等。用户权限=所拥有角色权限合集+用户加权限-用户减权限,优先级...
2--EL表达式可操作常量 变量 和隐式对象. 最常用的 隐式对象有${param}和${paramValues}. ${param}表示返回请求参数中单个字符串的值. ${paramValues}表示返回请求参数的一组 值.pageScope表示页面范围的变量....
{7.1}Java的文件系统管理}{103}{section.7.1} {7.2}回调模式与FileFilter}{104}{section.7.2} {7.3}\ttfamily RandomAccessFile}{106}{section.7.3} {7.4}基本类型数据序列化}{108}{section.7.4} {7.5}String的...
9.3.2 基于Spring管理JPA编写代码 212 9.4 小结 216 第10章 探索验证框架 217 10.1 熟悉数据验证框架 217 10.1.1 验证框架的架构 218 10.1.2 Struts 2工作流中的验证框架 219 10.2 将动作关联到验证框架 222 10.2.1...
1.4 第一个Java程序 8 1.4.1 开发源代码 8 1.4.2 编译运行 9 1.5 小结 11 第2章 基本数据类型——构建Java 大厦的基础 12 2.1 源代码注释 12 2.1.1 单行注释 12 2.1.2 区域注释 12 2.1.3 文档...
“一个视图(A View)”:应用程序中的任何JSF页面 “一次方法调用(A Method Call)”:通过EL表达式从流图调用应用逻辑 “一个开关(A Switch)”:在流图中基于布尔型EL表达式进行导航决策 “一次流调用(A ...
将Service层以下的代码放到一个新创建的java项目中,在部署的时候将Service(java项目)打成一个jar包,分别放到两个web服务中;编译的时候让web项目依赖与Service(java项目)_source folder;配置麻烦,项目与项目之间的...
7、基于Java平台开发,采用Spring、MySQL、Tomcat、Apache Kafka、Redis等开源技术,支持微服务,扩展性强。 8、许可证 Apache License, Version 2.0,开源免费。 MaxKey单点登录认证系统 更新日志: v2.7.0 ...
表单提交结束等4、前端常量维护: vue-enum,拒绝出现魔法数字,代码不可维护的现象5、全新的基于前端的权限设计(忘掉传统的权限设计吧,已经不适合这个前端时代)6、体验、交互更好用的员工、部门、角色、菜单管理7...
个配置表示一种struts的返回类型。struts-gpipe为struts返回类型添加了一个类型“gweb”,struts-gpipe会代理处 理index.ftl的渲染。3,脚本示例代码@GPipeMapping("m1") @Asyn class M1 implements GPipe{ ...
3、基于一个注解和controller的权限设计放弃更复杂的shiro 4、完整的数据权限支持 5、四层架构(controller, service, manager, dao) 6、代码阅读性强、扩展性极高的员工、部门、角色、菜单管理 7、基于LRU策略...