springboot 源码解析26-Liquiba 使⽤及LiquibaEndpoint 解析
前⾔
Liquiba是⼀个⽤于跟踪、管理和应⽤数据库变化的开源的数据库重构⼯具。它将所有数据库的变化(包括结构和数据)都保存在XML⽂件中,便于版本控制。
自然造物
那么在spring boot 中如何集成Liquiba,如何实现⾃动装配,如何通过actuator的⽅式对其进⾏监控,本⽂从以下3点来进⾏讲解:
1. spring boot与Liquiba 的集成
2. spring boot中Liquiba的⾃动装配源码分析
红灯笼怎么做3. spring boot actuator 中LiquibaEndpoint源码分析
spring boot 与Liquiba 的集成
1. 在l ⽂件中加⼊如下依赖:
由于我使⽤的spring boot 版本为1.5.9.RELEASE,其默认依赖liquiba-core的版本为3.5.3
当然,在项⽬中需要加⼊数据库的驱动,如下:
2.
在src/main/resources 下 创建 /db/changelog 的⽂件夹,如图:
3. 在 src/main/resources/db/changelog ⽬录下新建l,其内容如下:
<dependency >
<groupId >org.liquiba </groupId >
<artifactId >liquiba-core </artifactId >
</dependency >
<dependency >
<groupId >mysql </groupId >
<artifactId >mysql-connector-java </artifactId >
<scope >runtime </scope >
</dependency >
<?xml version="1.0" encoding="utf-8"?>
<databaChangeLog
xmlns ="www.liquiba/xml/ns/dbchangelog"
xmlns:xsi ="www.w3/2001/XMLSchema-instance"
xsi:schemaLocation ="www.liquiba/xml/ns/dbchangelog
www.liquiba/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<include file ="classpath:/db/l" relativeToChangelogFile ="fal"/>
<include file ="classpath:/db/l" relativeToChangelogFile ="fal"/>
</databaChangeLog >
其中relativeToChangelogFile = fal,说明配置的file路径为绝对路径,不需要通过相对路径去查找⽂件
4. l ⽂件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<databaChangeLog xmlns="www.liquiba/xml/ns/dbchangelog"
xmlns:xsi="www.w3/2001/XMLSchema-instance"
xsi:schemaLocation="www.liquiba/xml/ns/dbchangelog
www.liquiba/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<property name="autoIncrement"value="true"dbms="mysql" />
<changeSet id="2017-01-15"author="Harry">
<comment>init schema</comment>
<createTable tableName="ur">
<column name="id"type="bigint"autoIncrement="${autoIncrement}">
<constraints primaryKey="true"nullable="fal" />
</column>
<column name="nick_name"type="varchar(255)">
<constraints nullable="fal" />
</column>
<column name="email"type="varchar(255)">
<constraints nullable="fal" />
</column>
<column name="register_time"type="timestamp"
defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="fal" />
</column>
</createTable>
</changeSet>
</databaChangeLog>
其中changeSet 中的id 说明了本次变更的id,与author⼀起⽤于进⾏版本的跟踪
5. l 内容如下:
<?xml version="1.0" encoding="utf-8"?>
<databaChangeLog xmlns="www.liquiba/xml/ns/dbchangelog"
xmlns:xsi="www.w3/2001/XMLSchema-instance"
xsi:schemaLocation="www.liquiba/xml/ns/dbchangelog
www.liquiba/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<!-- 添加数据 -->
<changeSet id="2017-01-15-test-inrt"author="Harry">
<inrt tableName="ur">
<column name="nick_name"value="harry"/>
<column name="email"value=""/>
<column name="register_time"value="2017-01-15 22:00:02"/>
</inrt>
</changeSet>
<!-- 添加数据 -->
<changeSet id="2017-01-15-test-inrt-2"author="Harry">
<inrt tableName="ur">
<column name="nick_name"value="harry2"/>
<column name="email"value=""/>
<column name="register_time"value="2017-01-15 22:00:02"/>
</inrt>
</changeSet>
<!-- 修改字段 -->
<changeSet id="2017-01-15-test-chage"author="Harry">
<renameColumn tableName="ur"oldColumnName="email"newColumnName="email_new"columnDataType="varchar(255)"/> </changeSet>
</changeSet>
</databaChangeLog>
6. 在application.properties中加⼊如下配置:
\# liquiba 主配置⽂件的路径
liquiba.change-log=classpath:/db/l
liquiba.ur=xxx
liquiba.password=xxx
liquiba.url=你的数据库连接
\# 如果配置为true,则会每次执⾏时都会把对应的数据库drop掉,默认为fal
liquiba.drop-first=fal
7. 直接启动吧,启动完毕后就会发现在配置的数据库(liquiba.url)中有如下3张表:
1. databachangelog –> liquiba ⾃动创建,⽤于保存每次变更的记录,创建语句如下:
CREATE TABLE`databachangelog` (
`ID`varchar(255) NOT NULL,
`AUTHOR`varchar(255) NOT NULL,
`FILENAME`varchar(255) NOT NULL,
`DATEEXECUTED` datetime NOT NULL,
1976年属龙是什么命
`ORDEREXECUTED`int(11) NOT NULL,
`EXECTYPE`varchar(10) NOT NULL,
`MD5SUM`varchar(35) DEFAULT NULL,
`DESCRIPTION`varchar(255) DEFAULT NULL,
`COMMENTS`varchar(255) DEFAULT NULL,
`TAG`varchar(255) DEFAULT NULL,
`LIQUIBASE`varchar(20) DEFAULT NULL,
`CONTEXTS`varchar(255) DEFAULT NULL,
`LABELS`varchar(255) DEFAULT NULL,
`DEPLOYMENT_ID`varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. databachangeloglock–> liquiba ⾃动创建,创建语句如下:
CREATE TABLE`databachangeloglock` (
`ID`int(11) NOT NULL,
`LOCKED`bit(1) NOT NULL,
`LOCKGRANTED` datetime DEFAULT NULL,
`LOCKEDBY`varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. ur –> 我们配置的表
同时发现在ur表中的记录如下:
同时可以发现ur表中的email改为了email_new
⾄此,liquiba和spring boot 的集成就介绍到这⾥,更多的知识可以百度..
Liquiba⾃动装配
Liquiba ⾃动装配是在org.springframework.boot.autoconfigure.liquiba 包下,如图:
1. LiquibaProperties–> 个性化配置SpringLiquiba的配置类.该类声明了如下字段:
@ConfigurationProperties(prefix = "liquiba", ignoreUnknownFields = fal)
public class LiquibaProperties {
// 配置⽂件的路径
private String changeLog = "classpath:/db/changelog/db.changelog-master.yaml";
// 是否检查⽂件是否存在,默认为true
private boolean checkChangeLogLocation = true;
// 逗号分隔的运⾏上下⽂,在区分环境时有⽤
private String contexts;
// 默认的数据库库名
private String defaultSchema;
// 是否执⾏前先drop数据库,默认为fal
private boolean dropFirst;
// 是否开启liquiba的⽀持,默认为true
private boolean enabled = true;
白衣女门把手// ⽤来迁移数据的数据库⽤户名
private String ur;
// ⽤来迁移数据的数据库账户密码
同学聚会策划方案private String password;
// jdbc的链接
private String url;
// 逗号分隔的运⾏时使⽤的label
private String labels;
/
/ 参数
private Map<String, String> parameters;
// 当执⾏更新时回滚sql所在的⽂件
private File rollbackFile;
由于该类声明了@ConfigurationProperties(prefix = “liquiba”, ignoreUnknownFields = fal)注解,因此可以通过
<的⽅式进⾏配置,同时,如果配置的属性在LiquibaProperties没有对应值,会抛出异常.
2. @LiquibaDataSource –>指定要注⼊到Liquiba的数据源.如果该注解⽤于第⼆个数据源,则另⼀个(主)数据源通常需要被标记为
@Primary注解.代码如下:
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier
public @interface LiquibaDataSource {
}
3. LiquibaAutoConfiguration–> Liquiba的⾃动化配置类
年味的作文1. LiquibaAutoConfiguration 该类声明了如下注解:
有熊氏@Configuration
@ConditionalOnClass(SpringLiquiba.class)
@ConditionalOnBean(DataSource.class)
@ConditionalOnProperty(prefix = "liquiba", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
1. @Configuration–> 配置类
2. @ConditionalOnClass(SpringLiquiba.class)–> 在类路径下存在SpringLiquiba.class时⽣效
3. @ConditionalOnBean(DataSource.class)–> 在BeanFactory中存在DataSource类型的bean时⽣效
4. @ConditionalOnProperty(prefix = “liquiba”, name = “enabled”, matchIfMissing = true) –> 如果配置有
由于此时我们引⼊了liquiba-core,因此,该配置是默认⽣效的.
2. ⽼套路了,由于LiquibaAutoConfiguration有2个配置内部类,因此,在解析加载的时候会⾸先处理内部类.
1. LiquibaConfiguration
世界上最大的坦克1. 该类有如下注解:
@Configuration
@ConditionalOnMissingBean(SpringLiquiba.class)
@EnableConfigurationProperties(LiquibaProperties.class)
@Import(LiquibaJpaDependencyConfiguration.class)
1. @Configuration–> 配置类
2. @ConditionalOnMissingBean(SpringLiquiba.class) –> 当BeanFactory中缺少SpringLiquiba类型
的bean时⽣效
3. @EnableConfigurationProperties(LiquibaProperties.class) –> 引⼊LiquibaProperties配置类
4. @Import(LiquibaJpaDependencyConfiguration.class) –> 导⼊
LiquibaJpaDependencyConfiguration 配置类
2. 由于该类声明了@EnableConfigurationProperties(LiquibaProperties.class) 和
@Import(LiquibaJpaDependencyConfiguration.class)注解,因此在
ConfigurationClassParr#doProcessConfigurationClass中会⾸先调⽤processImports进⾏处理,此时获取的
是EnableConfigurationPropertiesImportSelector, LiquibaJpaDependencyConfiguration
1. EnableConfigurationPropertiesImportSelector:由于是ImportSelector的类型,因此会调⽤其
lectImports⽅法,该类返回的是
ConfigurationPropertiesBeanRegistrar,ConfigurationPropertiesBindingPostProcessorRegistrar.
接下来接着调⽤processImports 处理其返回值;
1. ConfigurationPropertiesBeanRegistrar –> 由于是ImportBeanDefinitionRegistrar的实例,因此会
加⼊到LiquibaConfiguration对应的ConfigurationClass的中的importBeanDefinitionRegistrars
2. ConfigurationPropertiesBindingPostProcessorRegistrar–>同样,由于是
ImportBeanDefinitionRegistrar的实例,加⼊到LiquibaConfiguration对应的ConfigurationClass的