需求:
由于项目中配置项太多,配置文件维护很不方便,将配置项放在数据库中维护,通过项目启动时将数据库配置加载到环境变量中,其他需要使用的业务直接使用引用的方式是@Value("${字段}")
项目结构:
pom.xml引入依赖包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.springboot</groupId> <artifactId>springboot-cache3</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-cache3</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 引入mybatis 数据库操作包 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 引入mybatis 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
配置日志记录
log4j.rootLogger=INFO, stdout , R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=${catalina.home}/logs/platform.log log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L %m%n log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.MaxFileSize=51200KB log4j.appender.R.MaxBackupIndex=10000 log4j.logger.org.springframework=ERROR log4j.logger.org.quartz=INFO #输出打印SQL语句,其中需要填写dao所在的包路径,不能使用模糊匹配 log4j.logger.com.example.spring=DEBUG
配置数据库连接
#server.port=8090 #标示使用的是mysql/oracle/sqlserver datasource.type=mysql #mysql数据连接 spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.username=root spring.datasource.password=root #spring.datasource.max-active=20 #spring.datasource.max-idle=8 #spring.datasource.min-idle=8 #spring.datasource.initial-size=20 #mybatis 配置 # 配置映射文件加载 mybatis.mapper-locations=classpath*:mapper/*.xml # 实体类通过别名使用 #mybatis.type-aliases-package=
表结构:
-- ---------------------------- -- Table structure for `test_tb_propertiesconf` -- ---------------------------- DROP TABLE IF EXISTS `test_tb_propertiesconf`; CREATE TABLE `test_tb_propertiesconf` ( `ConfKey` varchar(50) NOT NULL, `Remark` varchar(200) DEFAULT NULL, `ConfValue` varchar(50) NOT NULL, PRIMARY KEY (`ConfKey`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of test_tb_propertiesconf -- ----------------------------
创建初始化数据库配置类
package com.example.springboot.cache3.config; import com.example.springboot.cache3.dao.PropertiesMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; import javax.annotation.PostConstruct; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Pattern; /** * @Description: 动态加载数据库中的配置 * 然后根据数据库中的配置字段信息同步到上下文中让其它xml或者类引用, * 引用方式是xml通过${字段},类引用的方式是@Value("${字段}") */ @Configuration //order 控制初始化加载配置顺序,值越小加载越优先 @Order(value = 2) public class PropertiesConfig { private static final Log log = LogFactory.getLog(PropertiesConfig.class); // 声明一个对象用于存储数据库中的配置字段信息 private Properties properties = new Properties(); // 上下文环境信息 @Autowired private ConfigurableEnvironment env; // 调用查询数据库的dao @Autowired private PropertiesMapper propertiesMapper; // 查询配置文件表的SQL语句 private String query = "select ConfKey,ConfValue,Remark from WFBDCMain.dbo.ISIP_tb_PropertiesConf WITH (NOLOCK) where CurFlag > 0"; /** * 调用并初始化数据库中的配置字段到全局对象中 */ @PostConstruct private void initProperties() { log.info("数据库表配置-->读取数据表配置服务:开始!"); long startTime = System.nanoTime(); MutablePropertySources propertySources = env.getPropertySources(); try { List<Map<String, Object>> propertyMap = propertiesMapper.queryPropertiesConfg(); // 打印读取的数据表配置数据 log.debug(propertyMap.toString()); // 遍历所有数据表中的数据,然后把数据添加到properties配置字段中 for (Map<String, Object> tmp : propertyMap) { // 把数据表中的key和value添加到环境中 properties.put(tmp.get("ConfKey").toString(), tmp.get("ConfValue")); } PropertiesPropertySource dbPropertySource = new PropertiesPropertySource("dbPropertySource", properties); // 定义一个正则判断环境变量中是否存在相关的配置 Pattern p = Pattern.compile("^applicationConfig.*"); String name = null; boolean flag = false; for (PropertySource<?> source : propertySources) { if (p.matcher(source.getName()).matches()) { name = source.getName(); // 表示环境中存在该环境的配置,可以退出 flag = true; break; } } if (flag) { propertySources.addBefore(name, dbPropertySource); } else { propertySources.addFirst(dbPropertySource); } long endTime = System.nanoTime(); // 计算加载配置文件的耗时 double useTime = (endTime - startTime) / 1E9; log.info("数据库表配置-->读取数据表配置服务:结束,加载耗时:" + useTime + "秒!"); String key = env.getProperty("init_delay").toString(); log.info("数据库表配置-->" + key); } catch (Exception e) { // 错误信息打印 log.error("数据库表配置-->读取数据表配置服务异常: " + e); } } }创建mapper接口
package com.example.springboot.cache3.dao; import org.apache.ibatis.annotations.Mapper; import java.util.List; import java.util.Map; /** * @desc 加载数据库属性配置 * @Author wangsh * @date 2018/5/7 21:34 * @return */ @Mapper public interface PropertiesMapper { public List<Map<String, Object>> queryPropertiesConfg(); }
创建mapper配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.example.springboot.cache3.dao.PropertiesMapper"> <!-- 查询数据配置 --> <select id="queryPropertiesConfg" resultType="java.util.Map"> select ConfKey,ConfValue,Remark from test.test_tb_PropertiesConf where CurFlag > 0 </select> </mapper>
创建controller类
package com.example.springboot.cache3.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /** * @desc 测试读取数据库缓存配置 * @Author wangsh * @date 2018/5/7 20:57 */ @RestController @RequestMapping("/cache") public class CacheController { @Value("${init_delay}") private String init_delay; @ResponseBody @RequestMapping("/hello") public String hello() { System.out.println(">>>>>测试读取数据库缓存配置........" + init_delay); return init_delay; } }创建启动服务类
package com.example.springboot.cache3; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @MapperScan("com.example.springboot.cache3") @SpringBootApplication public class SpringbootCache3Application { public static void main(String[] args) { SpringApplication.run(SpringbootCache3Application.class, args); } }
启动服务测试如下
浏览器访问: http://localhost:8080/cache/hello
日志记录: