zoukankan      html  css  js  c++  java
  • 启动时数据库初始化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;
    }

  • 相关阅读:
    Vue2.0 $set()的正确使用方式
    Vue中axios踩坑之路-POST传参
    vue里使用create、mounted调用方法的正确姿势
    cmd返回上一级和根目录
    【积累】排序题积累
    【图论】2019 ICPC Malaysia National G(拓扑排序)
    2019 ICPC Malaysia National F(状态压缩)
    【线段树】扫描线学习笔记
    组合数(阶乘数质因子分解)
    【线段树】2019CCPC网络选拔赛 array(权值线段树)
  • 原文地址:https://www.cnblogs.com/perfectCats/p/15167441.html
Copyright © 2011-2022 走看看