• 启动时数据库初始化spring.datasource/spring.jpa


    springboot2.X之后需要增加 initialization-mode: always属性

    很多文章都没有说为什么,我这里把源码标记出来了。

    @Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
    public class DataSourceAutoConfiguration {

    // 引入了DataSourceInitializationConfiguration类

    @Configuration(proxyBeanMethods = false)
    @Import({ DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class })
    class DataSourceInitializationConfiguration {

    /**
    * {@link ImportBeanDefinitionRegistrar} to register the
    * {@link DataSourceInitializerPostProcessor} without causing early bean instantiation
    * issues.
    */
    static class Registrar implements ImportBeanDefinitionRegistrar {

    private static final String BEAN_NAME = "dataSourceInitializerPostProcessor";

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
    BeanDefinitionRegistry registry) {
    // 这里判断是否有dataSourceInitializerPostProcessor这个bean,如果没有则会创建
    if (!registry.containsBeanDefinition(BEAN_NAME)) {
    GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
    beanDefinition.setBeanClass(DataSourceInitializerPostProcessor.class);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // We don't need this one to be post processed otherwise it can cause a
    // cascade of bean instantiation that we would rather avoid.
    beanDefinition.setSynthetic(true);
    registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
    }
    }

    }

    }


    class DataSourceInitializerPostProcessor implements BeanPostProcessor, Ordered {

    @Override
    public int getOrder() {
    return Ordered.HIGHEST_PRECEDENCE + 1;
    }

    @Autowired
    private BeanFactory beanFactory;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof DataSource) {
    // force initialization of this bean as soon as we see a DataSource
    // 如果bean是DataSource类型,就会获取DataSourceInitializerInvoker这个类
    this.beanFactory.getBean(DataSourceInitializerInvoker.class);
    }
    return bean;
    }

    }

    @Override
    public void afterPropertiesSet() {
    DataSourceInitializer initializer = getDataSourceInitializer();
    if (initializer != null) {
    // 这里有一个判断是否创建Schema
    boolean schemaCreated = this.dataSourceInitializer.createSchema();
    if (schemaCreated) {
    initialize(initializer);
    }
    }
    }

    boolean createSchema() {
    List<Resource> scripts = getScripts("spring.datasource.schema", this.properties.getSchema(), "schema");
    if (!scripts.isEmpty()) {
    if (!isEnabled()) {
    logger.debug("Initialization disabled (not running DDL scripts)");
    return false;
    }
    String username = this.properties.getSchemaUsername();
    String password = this.properties.getSchemaPassword();
    runScripts(scripts, username, password);
    }
    return !scripts.isEmpty();
    }

    // 如果是NEVER或者是EMBEDDED就不会创建,所以我们要在配置文件中增加initialization-mode: always属性
    private boolean isEnabled() {
    DataSourceInitializationMode mode = this.properties.getInitializationMode();
    if (mode == DataSourceInitializationMode.NEVER) {
    return false;
    }
    if (mode == DataSourceInitializationMode.EMBEDDED && !isEmbedded()) {
    return false;
    }
    return true;
    }

  • 相关阅读:
    阻止a链接跳转的点击事件
    appium python版api
    Appium—python_ 安卓手机划屏幕操作
    appium-unittest框架中的断言
    Appium 服务关键字
    python mysql入库的时候字符转义
    python实现两个字典合并
    解决linux登录后总是时间过会就断开(解决ssh登录后闲置时间过长而断开连接)
    linux安装好redis,如何在window端访问?
    linux上安装redis
  • 原文地址:https://www.cnblogs.com/perfectCats/p/15167441.html
Copyright © 2020-2023  润新知