java 常量维护_一种基于Spring的java程序常量管理思路

本文探讨了在大型项目中如何有效管理常量,特别是业务性常量。通过使用Spring的属性注入,可以将常量配置在Properties文件中,从而避免重复定义和循环依赖的问题。文章介绍了定义一个Annotation、实现Annotation Processor、配置Processor Bean的步骤,并给出了使用示例,实现了在部署期间灵活覆盖编译期常量值的功能。
摘要由CSDN通过智能技术生成

在编写程序的时候,总是不可避免的需要使用一些常量,甚至很多的常量。我们可以对常量进行一个很简单的分类:

记忆性常量:主要出于程序结构上的考虑而设定的常量。譬如为了避免一个没有字面意思的魔法数,或者避免拼写容易出错,或者不容记住的内容。

业务性常量:表示一个业务上的一个特定业务实体的属性或属性值。

很多的时候,一个业务性常量很多时候也是一个记忆性常量。

在一个大型项目中,参与的人员和代码数量通常都会比较多,没有好的管理策略,常量的使用往往想入混乱中。譬如重复定义,其维护的值甚至还不一致,以外覆盖;譬如仅仅为了使用某个常量,而引入某个包或者类,由此可能引出模块间的循环依赖等。

良好的设计结构,以及严格的开发纪律基本上可以解决上述问题。除了有时的确是不可避免的出现以上问题外,有时一些所谓的业务常量只有在部署期间或同别的系统集成是才能获得。所以有必要进一步的探讨常量的管理手段。

记得在JavaEye上看到一篇关于Spring属性注入的文章,灵机一动,不是恰好可以用来处理这个问题吗?所谓属性注入,意思是指将配置信息写在Properties文件中,通过IOC容器透明的注入。

这么设想下,如果常量最终都可以用配置文件配置,那么就可以解决“业务常量只有在部署期间或同别的系统集成是才能获得”的问题,如果同时还可以透明的宣称使用常量,那么几乎所有的问题就完美了:

不害怕重复定义错误

消除有常量引用引起的循环引用

提供从部署期覆盖编译期的灵活性

使用Spring的扩展名称空间和Java5的Annotation语法,我们可以整理出以以下思路

定义一个Annotation类

实现一个Annotation的Processor

配置Processor Bean

实现过程大致如下:

一、Annotation

Java代码  ad3bfa377f914991041a8454b882026f.png

@Target({ElementType.FIELD,ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

public@interfaceProperties {

String name() default"";

String value() default"";

String namePrefix() default"";

String namePostfix() default"";

}

二、Processor

Java代码  ad3bfa377f914991041a8454b882026f.png

publicclassAnnotationPropertiesBeanPostProcessorextendsPropertyPlaceholderConfigurerimplementsBeanPostProcessor, InitializingBean {

privatejava.util.Properties pros;

privateString namePrefix ="";

privateString namePostfix ="";

publicvoidsetEnabledClassList(Class[] enabledClassList) {

this.enabledClassList = enabledClassList;

}

publicObject postProcessAfterInitialization(Object bean, String beanName)throwsBeansException {

returnbean;

}

@Override

publicObject postProcessBeforeInitialization(Object bean, String beanName)throwsBeansException {

HandlePropertiesAnnotatedBean(bean, bean.getClass());

returnbean;

}

privatevoidHandlePropertiesAnnotatedBean(Object bean, Class> asClass)throwsSecurityException {

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));

}

}

}

privatevoidhandleField(Object bean, Field field,booleandefaultIsRequired) {

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

Xml代码  ad3bfa377f914991041a8454b882026f.png

四、使用实例

Java代码  ad3bfa377f914991041a8454b882026f.png

@Properties(namePrefix="ddd")

publicclassConfig {

@Properties(name="author")

privateString author;

privateString tvalue;

@Properties(value="default name",namePrefix="ooo")

privateString tname;

privateString nonValue;

// getter and setter

}

五、示例Properties文件内容

Xml代码  ad3bfa377f914991041a8454b882026f.png

dddauthor=用的是 class 级别的 prefix

oootname=用的是 field 级别的 prefix

dddnonValue=用sd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值