Spring实现从数据库加载资源配置信息
Spring在很多项目中都有应用,作为IOC容器和处理依赖关系。在处理依赖的时候不仅能根据类型注入相应的bean还能从资源文件中读取配置,给一些基本类型的数据进行初始化赋值,这一类多见于系统的配置信息或者一些路径信息。
Spring提供了从资源文件中读取这些信息,任何方式都有弊端,放在资源文件中,管理起来不方便,不能做一些共性控制.但是相对来说开发人员使用起来简单,更改测试都很方便。
如果把spring的配置文件从数据库加载怎么做呢…
这里我设计了2张表,使用组别(group)和具体配置项(property)的关系来对配置信息做区分。
在组别表中存放一些选择配置的条件,比如:关键词、IP地址、加载顺序。
在配置项表中主要就是资源配置文件中的键值对形式的数据,另外还有些默认值和注释的字段。
采用这样的设计,我的想发是能够通过条件和关键词区分出不同的配置,最大化的方便开发和生产的测试和开发需求。
比如开发人员小B想在应用配置中有一份自己专属的配置,因为在数据库中,为了达到相互不影响,就需要根据一些条件能区分开,可以是物理机器上的区分、也可以是应用上的区分,还可以是JAVA虚拟机的区分.这里使用了IP区分。
另外一种是应用的配置项很多,小B不想去为自己的配置copy那么多的配置信息,这时,应该可以让小B优先使用默认的配置,然后使用自己配置一些特定信息覆盖掉默认配置,达到自定义的目的。
除了上面的从数据库加载配置,应该还需要保留从资源文件加载配置的功能,兼容未做数据库的配置信息。
先看下表结构:
CREATE TABLE `property_group` ( `id` int(11) NOT NULL AUTO_INCREMENT , `key` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '应用加载的key' , `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '分组名称' , `address` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '对应的IP地址,为*则匹配所有' , `master` int(2) NOT NULL DEFAULT 0 COMMENT '是否为主要配置,不匹配IP地址时,已此做加载判断' , `sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序,值越大,越后加载。' , PRIMARY KEY (`id`), UNIQUE INDEX `key` USING BTREE (`key`, `address`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=9 ROW_FORMAT=COMPACT ; CREATE TABLE `property_config` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT , `group` int(11) UNSIGNED NOT NULL COMMENT '分组ID' , `name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '配置项名称' , `value` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '配置项的值' , `defvalue` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '配置项的默认值' , `available` int(2) NULL DEFAULT 0 COMMENT '是否可用' , `desc` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '此配置项的描述' , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=90 ROW_FORMAT=COMPACT ;
—————————————————G—————————————————- 核心的功能由DataSourcePlaceholderConfigurer实现,这个类继承了PropertyPlaceholderConfigurer类, 并实现了BeanNameAware,BeanFactoryAware两个接口。 在调用的时候传入以上的参数,数据库部分传入一个数据源,用于加载配置。addressSelector表示是否使用IP选择配置信息, 如果为true,则获取当前应用IP去数据库查询符合条件的配置组别和具体配置。 主要的加载操作都由一个覆盖了PropertyResourceConfigurer的方法postProcessBeanFactory来处理的:
try { Properties mergedProps = mergeProperties(); mergeDataSourceProperties(mergedProps); //从数据库加载配置信息 // Convert the merged properties, if necessary. convertProperties(mergedProps); //从资源文件加载配置信息,会覆盖掉数据库同名参数 // Let the subclass process the properties. processProperties(beanFactory, mergedProps); } catch (IOException ex) { throw new BeanInitializationException("Could not load properties", ex); }
下面来看下mergeDataSourceProperties具体实现: 这里实现了根据不同的参数来匹配数据库的配置,并加入到配置集合,最后再由spring来进行配置注入。 主要的核心方法就是这些,剩下就是些IP获取、IP匹配、JdbcTemplate的调用方法了。 采用这样的数据库配置,如果配置文件通过数据库来做更改,不太直观,如果有一个WEB界面来可视化的管理这2张表, 能够方便的创建自己的分组合配置文件,应该是很方便的。