Configuration of datasource in Spring boot

In spring boot, there is a datasource automatic configuration class in the package spring-boot-autoconfigure

wrote
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

 In the configuration file application.properties, after configuring spring.datasource.*, the datasource will be automatically configured

	@Conditional(DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	protected static class NonEmbeddedConfiguration {

		@Autowired
		private DataSourceProperties properties;

		@Bean
		@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
		public DataSource dataSource() {
			DataSourceBuilder factory = DataSourceBuilder
					.create(this.properties.getClassLoader())
					.driverClassName(this.properties.getDriverClassName())
					.url(this.properties.getUrl()).username(this.properties.getUsername())
					.password(this.properties.getPassword());
			if (this.properties.getType() != null) {
				factory.type(this.properties.getType());
			}
			return factory.build();
		}

	}

 But there is a condition

@Conditional(DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition.class)

 It means that it will only be configured when there is a non-embedded DataSource, and the condition of the judgment is actually written in the DataSourceBuilder

	private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
			"org.apache.tomcat.jdbc.pool.DataSource",
			"com.zaxxer.hikari.HikariDataSource",
			"org.apache.commons.dbcp.BasicDataSource",
			"org.apache.commons.dbcp2.BasicDataSource" };

 That is to say, these classes listed above must exist in the system.

 

So if you configure spring.datasource.* related information in application.properties and find that there is no datasource bean, it means that you can forget to add the above packages.

 

Although spring boot does a lot for us, it seems to be sneaky. If you don't understand the internal implementation, you may encounter situations that are sometimes effective and sometimes ineffective.

For peace of mind, you can also specify these configurations yourself.

@Configuration
public class DbConfiguration implements TransactionManagementConfigurer {
	
	@Autowired
	private DataSourceProperties properties;
	
	@Bean
	public DataSource dataSource() {
		DataSourceBuilder factory = DataSourceBuilder
				.create(this.properties.getClassLoader())
				.driverClassName(this.properties.getDriverClassName())
				.url(this.properties.getUrl()).username(this.properties.getUsername())
				.password(this.properties.getPassword());
		if (this.properties.getType() != null) {
			factory.type(this.properties.getType());
		}
		return factory.build();
	}

    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }

	@Override
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return txManager();
	}

}

 The interface: TransactionManagementConfigurer is implemented here. When there are multiple transaction managers, the default transaction manager declared with annotations is specified here. For example, when Transactional is used, transactionManager is not specified.

application.properties

wrote
spring.datasource.url=jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

 Of course, you can create DataSource directly instead of using DataSourceBuilder.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326796002&siteId=291194637