一、SpringBoot中常量数据的配置
在使用SpringBoot实现项目时,总是存在一些需要配置的常量信息,例如相册系统中中配置相册文件夹的位置、配置相册默认存储大小等,又例如考勤系统中配置考勤时间等等。
这些常量数据有3种方法实现。
1、直接写死在代码里。通过public final static
定义一个常量,然后使用该常量。 如果需要修改变量值,需要修改JAVA代码,需要重新编译成war包或jar包。对于真常量、不会发生变化的情形可以使用该方式。
2、写在配置文件中,例如直接写在application.yml中。这种方法中如果要修改配置,需要修改war包或jar包中的配置文件,虽然不需要重新编译JAVA代码,但涉及修改代码包,也是不安全的操作。
3、将可能会变动的配置放在数据库中,在启动项目时去数据库中读取常量信息,然后缓存成为JAVA对象,全局都可以使用。如果修改常量值,直接修改数据库即可。
以上三种方法修改之后,都需要重新启动项目。针对在不同情况下可能需要自定义人工赋值的常量,推荐使用第三种方法,下面具体讲解这种使用数据库缓存常量数据的实现方式。
二、使用数据库实现常量数据缓存
(一)创建系统常量表sys_config
(二)读取数据
创建常量封装类
//常量封装类需要使用@Component注入到SpringBoot容器池中
//使用@Data代替setter和getter的实现
@Data
@Component
public class SystemConstants {
public String attendanceStartTime;
public String attendanceTime;
public String attendanceEndTime;
public String closingStartTime;
public String closingTime;
public String closingEndTime;
}
声明Dao层抽象方法
@Mapper
public interface SysConfigDao {
public List<SysConfig> selectAllParam();
}
对应的sql如下
<select id="selectAllParam" resultType="com.example.emos.wx.db.pojo.SysConfig">
SELECT param_key, param_value FROM sys_config WHERE status = 1;
</select>
在启动类中创建sysInit方法,读取常量数据并缓存。
此处使用的SpringBoot中的Bean初始化方法的@PostConstruct
注解来实现。在执行顺序上, 构造方法
-> @Autowired
-> @PostConstruct
。在Bean初始化之后(构造方法和@Autowired之后)才会执行@PostConstruct
注解下的指定操作,这样保证@PostConstruct
注解下可以使用SpringBoot容器中已经注入的对象。
@SpringBootApplication
@ServletComponentScan
@Slf4j
public class EmosWxApiApplication {
@Autowired
private SysConfigDao sysConfigDao;
@Autowired
private SystemConstants constants;
public static void main(String[] args) {
SpringApplication.run(EmosWxApiApplication.class, args);
}
@PostConstruct
public void sysInit() {
List<SysConfig> list = sysConfigDao.selectAllParam();
list.forEach(one -> {
String key = one.getParamKey();
key = StrUtil.toCamelCase(key);
String value = one.getParamValue();
try {
Field field = constants.getClass().getDeclaredField(key);
field.set(constants, value);
} catch (Exception e) {
log.error("执行异常", e);
}
});
}
}
以上代码,首先在启动类中注入了一个SystemConstants
类的Bean,注入这个bean之后,在sysInit
方法中通过反射给这个对象的成员变量赋值,然后就可以全局使用该对象,获取对应的常量值了。
为什么可以直接全局使用呢,这是很好的利用了SpringBoot中依赖注入中的单例模式。在Spring中Bean的作用域总共定义了6种,其中默认为单例模式(Singleton
),也就是在每个Spring IOC容器中,一个JAVA类只会有唯一的一个bean实例。
所以,从SpringBoot启动之后,通过反射首先给这个配置类进行了赋值。之后在其他任何地方使用的这个对象,都是同一个对象,也就是成员变量的值都是同一个,所以也就是全局可以共享常量值。