SSM 整合使用 @PropertySource 问题

SSM 整合使用 @PropertySource 问题

如果你想将数据库连接的相关属性移入一个 classpath 下的 “.properties” 文件中,让后再在上述配置类中结合 @PropertySource@Value 来加载 .properties 配置文件,引入相关属性值,那么,你会发现一个问题,你的 @Value 读取到的属性值都是 null

造成这个现象的原因在在于,我们是使用的 MapperScannerConfigurer 进行的『包扫描』的工作,而 MapperScannerConfigurer 开始『干活』的时机要比 @PropertySource 早!这就导致了,当你去读取标注了 @Value 的属性的值时,@PropertySource 还没有为它们赋值。

解决办法
@Value 属性(甚至包括数据库的单例配置)拆分出去,配置成一个单独的 JavaBean,再通过 @Autowired 引入回来,变相强迫 Spring 在 MapperScannerConfigurer 进行包扫描前先处理它们。

被拆分出去的 @Value

@Data
@Component
@PropertySource("classpath:jdbc.properties")
public class DataBaseProperties {

    @Value("${jdbc.driverClassName}")
    private String driverClassName;

    @Value("${jdbc.jdbcUrl}")
    private String jdbcUrl;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;
}

再『引入』进来

@Configuration
public class SpringDaoConfig {
        
  ...

  /*
    @Bean(initMethod = "init", destroyMethod = "close")
    public DruidDataSource dataSource(DataBaseProperties properties) {
      DruidDataSource ds = new DruidDataSource();
            ds.setDriverClassName(properties.getDriverClassName());
      ds.setUrl(properties.getJdbcUrl());
      ds.setUsername(properties.getUsername());
    ds.setPassword(properties.getPassword());
    return ds;
  }
  */

  @Bean(destroyMethod = "close")
  public HikariDataSource dataSource(DataBaseProperties properties) {
    HikariDataSource ds = new HikariDataSource();
            ds.setDriverClassName(properties.getDriverClassName());
    ds.setJdbcUrl(properties.getJdbcUrl());
    ds.setUsername(properties.getUsername());
    ds.setPassword(properties.getPassword());
    return ds;
  }

  ...
}

你可能感兴趣的:(spring,数据库,java,spring)