Commit 5777eddf authored by 375242562@qq.com's avatar 375242562@qq.com

Initial commit

parents
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
<option name="TYPE_ANNOTATION_LOCAL_DEFINITION" value="true" />
<option name="TYPE_ANNOTATION_EXCLUDE_WHEN_TYPE_IS_STABLE" value="false" />
</ScalaCodeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="liquibase-core-starter" />
</profile>
</annotationProcessing>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpringJavaConstructorAutowiringInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SpringJavaInjectionPointsAutowiringInspection" enabled="false" level="ERROR" enabled_by_default="false" />
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="maven-public" />
<option name="name" value="maven-public" />
<option name="url" value="http://116.211.118.67:50003/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="aliyun" />
<option name="name" value="aliyun" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://116.211.118.67:50003/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?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>org.liquibase.core</groupId>
<artifactId>liquibase-spring-core-starter</artifactId>
<version>4.31.3</version>
<name>liquibase-spring-core-starter</name>
<developers>
<developer>
<name>Brother, stop looking and run away quickly</name>
<email>runrunrun@shit.com</email>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<!-- 编译时的编码 -->
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<liquibase.version>4.31.2</liquibase.version>
<spring-boot.version>2.4.2</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<distributionManagement>
<repository>
<id>maven-releases</id>
<url>http://116.211.118.67:50003/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<url>http://116.211.118.67:50003/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.liquibase.core.configuration;
import liquibase.changelog.visitor.ChangeExecListener;
import org.liquibase.core.liquibase.LiquibaseCreator;
import org.liquibase.core.property.DynamicProperty;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.List;
@Configuration
@EnableConfigurationProperties(DynamicLiquibaseProperties.class)
@ConditionalOnProperty(prefix = DynamicLiquibaseProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
public class DynamicLiquibaseConfiguration {
public static final String SPRING_LIQUIBASE = "SpringLiquibase";
private final ConfigurableListableBeanFactory beanFactory;
private final DynamicLiquibaseProperties properties;
private final List<ChangeExecListener> listeners;
private final List<DynamicProperty<?>> dynamicProperties;
private final DataSource dataSource;
public DynamicLiquibaseConfiguration(ConfigurableListableBeanFactory beanFactory,
DynamicLiquibaseProperties properties,
List<ChangeExecListener> listeners,
List<DynamicProperty<?>> dynamicProperties,
DataSource dataSource) {
this.beanFactory = beanFactory;
this.properties = properties;
this.listeners = listeners;
this.dynamicProperties = dynamicProperties;
this.dataSource = dataSource;
}
@Bean
public LiquibaseCreator liquibaseCreator() {
return new LiquibaseCreator(beanFactory, properties, listeners, dynamicProperties, dataSource);
}
}
package org.liquibase.core.configuration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author LENOVO
* @date 2025/3/14 11:19
*/
@ConfigurationProperties(prefix = DynamicLiquibaseProperties.PREFIX)
public class DynamicLiquibaseProperties {
public static final String PREFIX = "spring.liquibase.dynamic";
private boolean enabled = true;
private LiquibaseProperties config;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public LiquibaseProperties getConfig() {
return config;
}
public void setConfig(LiquibaseProperties config) {
this.config = config;
}
}
package org.liquibase.core.liquibase;
import liquibase.Liquibase;
import liquibase.changelog.ChangeLogParameters;
import liquibase.changelog.visitor.ChangeExecListener;
import liquibase.changelog.visitor.DefaultChangeExecListener;
import liquibase.database.Database;
import liquibase.exception.DatabaseException;
import liquibase.exception.LiquibaseException;
import liquibase.integration.spring.SpringLiquibase;
import liquibase.integration.spring.SpringResourceAccessor;
import liquibase.resource.ResourceAccessor;
import org.liquibase.core.property.DynamicProperty;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.core.io.DefaultResourceLoader;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author LENOVO
* @date 2025/3/14 11:06
*/
public class DynamicSpringLiquibase extends SpringLiquibase implements DisposableBean {
/**
* 监听器
*/
private List<ChangeExecListener> listeners = new ArrayList<>();
/**
* 动态属性
*/
private List<DynamicProperty<?>> dynamicProperties = new ArrayList<>();
public DynamicSpringLiquibase() {
super();
}
public DynamicSpringLiquibase(LiquibaseProperties properties,
String applicationId,
DataSource dataSource) {
super();
setDataSource(dataSource);
setChangeLog(properties.getChangeLog());
setClearCheckSums(properties.isClearChecksums());
setContexts(properties.getContexts());
setDefaultSchema(properties.getDefaultSchema());
setLiquibaseSchema(properties.getLiquibaseSchema());
setLiquibaseTablespace(properties.getLiquibaseTablespace());
setDatabaseChangeLogTable(properties.getDatabaseChangeLogTable());
setDatabaseChangeLogLockTable(properties.getDatabaseChangeLogLockTable());
setDropFirst(properties.isDropFirst());
setApplicationId(applicationId);
setShouldRun(properties.isEnabled());
setLabelFilter(properties.getLabels());
setChangeLogParameters(properties.getParameters());
setRollbackFile(properties.getRollbackFile());
setTestRollbackOnUpdate(properties.isTestRollbackOnUpdate());
setTag(properties.getTag());
setResourceLoader(new DefaultResourceLoader());
setListeners(listeners);
setDynamicProperties(dynamicProperties);
}
@Override
protected Liquibase createLiquibase(Connection c) throws LiquibaseException {
Liquibase liquibase = super.createLiquibase(c);
addListener(liquibase);
addDynamicProperties(liquibase);
return liquibase;
}
@Override
protected Database createDatabase(Connection c, ResourceAccessor resourceAccessor) throws DatabaseException {
return super.createDatabase(c, resourceAccessor);
}
@Override
protected SpringResourceAccessor createResourceOpener() {
return super.createResourceOpener();
}
private void addListener(Liquibase liquibase) {
DefaultChangeExecListener defaultChangeExecListener = liquibase.getDefaultChangeExecListener();
listeners.forEach(defaultChangeExecListener::addListener);
liquibase.setChangeExecListener(defaultChangeExecListener);
}
// public void addListeners(List<ChangeExecListener> listeners) {
// if (listeners != null) {
// this.listeners.addAll(listeners);
// }
// }
private void addDynamicProperties(Liquibase liquibase) {
ChangeLogParameters changeLogParameters = liquibase.getChangeLogParameters();
for (DynamicProperty<?> dynamicProperty : dynamicProperties) {
Object value = dynamicProperty.getValue();
if (value == null) {
continue;
}
if (value instanceof Map) {
Map<String, Object> items = (Map<String, Object>) value;
items.forEach((key, val) -> {
changeLogParameters.set(key, val, null, (String) null,
dynamicProperty.getDbms(), true, null);
});
} else {
changeLogParameters.set(dynamicProperty.getName(), dynamicProperty, null, (String) null,
dynamicProperty.getDbms(), true, null);
}
}
}
// public void addDynamicProperties(List<DynamicProperty<?>> dynamicProperties) {
// if (dynamicProperties != null) {
// this.dynamicProperties.addAll(dynamicProperties);
// }
// }
@Override
public void destroy() throws Exception {
DataSource dataSource = getDataSource();
if (dataSource instanceof AutoCloseable) {
AutoCloseable c = (AutoCloseable) dataSource;
try {
c.close();
} catch (Exception ignored) {
}
}
}
public void setListeners(List<ChangeExecListener> listeners) {
if (listeners != null) {
this.listeners.addAll(listeners);
}
this.listeners = listeners;
}
public void setDynamicProperties(List<DynamicProperty<?>> dynamicProperties) {
if (dynamicProperties != null) {
this.dynamicProperties.addAll(dynamicProperties);
}
}
@Override
public String toString() {
return getClass().getName() + "(" + beanName + ")";
}
}
package org.liquibase.core.liquibase;
import liquibase.changelog.visitor.ChangeExecListener;
import liquibase.exception.LiquibaseException;
import lombok.extern.slf4j.Slf4j;
import org.liquibase.core.configuration.DynamicLiquibaseConfiguration;
import org.liquibase.core.configuration.DynamicLiquibaseProperties;
import org.liquibase.core.property.DynamicProperty;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.wiring.BeanWiringInfo;
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;
import org.springframework.beans.factory.wiring.ClassNameBeanWiringInfoResolver;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.core.io.DefaultResourceLoader;
import javax.sql.DataSource;
import java.util.List;
import java.util.Objects;
@Slf4j
public class LiquibaseCreator implements DisposableBean {
private final ConfigurableListableBeanFactory beanFactory;
private final DynamicLiquibaseProperties properties;
private final List<ChangeExecListener> listeners;
private final List<DynamicProperty<?>> dynamicProperties;
private final DataSource dataSource;
public LiquibaseCreator(ConfigurableListableBeanFactory beanFactory,
DynamicLiquibaseProperties properties,
List<ChangeExecListener> listeners,
List<DynamicProperty<?>> dynamicProperties,
DataSource dataSource) {
this.beanFactory = beanFactory;
this.properties = properties;
this.listeners = listeners;
this.dynamicProperties = dynamicProperties;
this.dataSource = dataSource;
}
public void createLiquibaseBeanDefinition(String applicationId) throws LiquibaseException {
if (!properties.isEnabled()) {
log.info("Init liquibase bean not enable.");
return;
}
String beanName = getBeanName("default");
if (beanFactory.containsBeanDefinition(beanName) || beanFactory.containsBean(beanName)) {
log.info("Bean '{}' already exists, skipping creation.", beanName);
DynamicSpringLiquibase liquibaseBean = (DynamicSpringLiquibase) beanFactory.getBean(beanName);
liquibaseBean.afterPropertiesSet();
return;
}
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DynamicSpringLiquibase.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
// 设置构造函数参数
ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addIndexedArgumentValue(0, properties.getConfig());
args.addIndexedArgumentValue(1, applicationId);
args.addIndexedArgumentValue(2, getTargetDataSource());
beanDefinition.setConstructorArgumentValues(args);
// 设置属性值(如果需要)
MutablePropertyValues propertyValues = new MutablePropertyValues();
// 如果需要设置其他属性,可以在这里添加
propertyValues.add("listeners", listeners);
propertyValues.add("dynamicProperties", dynamicProperties);
beanDefinition.setPropertyValues(propertyValues);
// 设置初始化方法(如果有)
// beanDefinition.setInitMethodName("init");
// 注册 BeanDefinition
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanName, beanDefinition);
// 立即初始化这个Bean(对于单例Bean)
if (!beanFactory.isCurrentlyInCreation(beanName)) {
beanFactory.getBean(beanName);
}
log.info("Init liquibase bean definition success");
}
public void createLiquibase(String applicationId) {
if (!properties.isEnabled()) {
log.info("Init liquibase bean not enable.");
return;
}
BeanWiringInfoResolver bwiResolver = new ClassNameBeanWiringInfoResolver();
String beanName = getBeanName("default");
DynamicSpringLiquibase springLiquibase = springLiquibase(properties.getConfig(), applicationId);
springLiquibase.setBeanName(beanName);
BeanWiringInfo bwi = bwiResolver.resolveWiringInfo(springLiquibase);
if (bwi == null) {
// Skip the bean if no wiring info given.
log.info("Skip the bean if no wiring info given.");
return;
}
if (bwi.indicatesAutowiring() || bwi.isDefaultBeanName() && !beanFactory.containsBean(beanName)) {
beanFactory.autowireBeanProperties(springLiquibase, bwi.getAutowireMode(), bwi.getDependencyCheck());
beanFactory.initializeBean(springLiquibase, beanName);
} else {
beanFactory.configureBean(springLiquibase, beanName);
}
if (!beanFactory.containsBean(beanName)) {
beanFactory.registerSingleton(beanName, springLiquibase);
}
log.info("Init liquibase bean success");
}
private DynamicSpringLiquibase springLiquibase(LiquibaseProperties properties, String applicationId) {
DynamicSpringLiquibase liquibase = new DynamicSpringLiquibase();
liquibase.setDataSource(getTargetDataSource());
liquibase.setChangeLog(properties.getChangeLog());
liquibase.setClearCheckSums(properties.isClearChecksums());
liquibase.setContexts(properties.getContexts());
liquibase.setDefaultSchema(properties.getDefaultSchema());
liquibase.setLiquibaseSchema(properties.getLiquibaseSchema());
liquibase.setLiquibaseTablespace(properties.getLiquibaseTablespace());
liquibase.setDatabaseChangeLogTable(properties.getDatabaseChangeLogTable());
liquibase.setDatabaseChangeLogLockTable(properties.getDatabaseChangeLogLockTable());
liquibase.setDropFirst(properties.isDropFirst());
liquibase.setApplicationId(applicationId);
liquibase.setShouldRun(properties.isEnabled());
liquibase.setLabelFilter(properties.getLabels());
liquibase.setChangeLogParameters(properties.getParameters());
liquibase.setRollbackFile(properties.getRollbackFile());
liquibase.setTestRollbackOnUpdate(properties.isTestRollbackOnUpdate());
liquibase.setTag(properties.getTag());
liquibase.setResourceLoader(new DefaultResourceLoader());
liquibase.setListeners(listeners);
liquibase.setDynamicProperties(dynamicProperties);
return liquibase;
}
public DataSource getTargetDataSource() {
Objects.requireNonNull(dataSource, "dataSource must not be null");
return dataSource;
}
public String getBeanName(String liquibaseType) {
return liquibaseType + DynamicLiquibaseConfiguration.SPRING_LIQUIBASE;
}
@Override
public void destroy() throws Exception {
String beanName = getBeanName("default");
if (beanFactory.containsBean(beanName)) {
DynamicSpringLiquibase liquibase = beanFactory.getBean(beanName, DynamicSpringLiquibase.class);
liquibase.destroy();
}
}
}
package org.liquibase.core.liquibase;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import java.util.HashMap;
import java.util.Map;
public class LiquibaseStartupListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
// set liquibase env
Map<String, Object> propertyMap = new HashMap<>();
propertyMap.put("spring.liquibase.enabled", false);
propertyMap.put("spring.liquibase.dynamic.config.change-log", "classpath:migration/changelog-master.xml");
propertyMap.put("spring.liquibase.dynamic.config.databaseChangeLogTable", "MG_LIQUIBASE_LOG");
propertyMap.put("spring.liquibase.dynamic.config.databaseChangeLogLockTable", "MG_LIQUIBASE_LOCK");
propertyMap.put("spring.liquibase.dynamic.config.clearChecksums", true);
propertySources.addFirst(new MapPropertySource("default_liquibase_env_property", propertyMap));
}
}
package org.liquibase.core.property;
import java.util.Objects;
public abstract class DynamicProperty<T> {
/**
* 获取属性名称
*
* @return
*/
public abstract String getName();
/**
* 获取属性值
*
* @return
*/
public abstract T getValue();
/**
* 数据库管理系统
*
* @return
*/
public String getDbms() {
return null;
}
@Override
public String toString() {
Object value = getValue();
Objects.requireNonNull(value, "value must not be null");
return value.toString();
}
}
org.springframework.context.ApplicationListener=\
org.liquibase.core.liquibase.LiquibaseStartupListener
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.liquibase.core.configuration.DynamicLiquibaseConfiguration
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment