spring boot自动配置之jdbc
1.DataSource配置
1.1 默認配置application.xml
spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=root spring.datasource.password=****spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.type=com.zaxxer.hikari.HikariDataSource
需要在pom.xml加入依賴(我使用了mybatis+mysql)
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis-spring.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency> <dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<exclusions>
<exclusion>
<artifactId>tools</artifactId>
<groupId>com.sun</groupId>
</exclusion>
</exclusions>
</dependency>
2.自定義DataSource
1.1 application.xml配置文件
spring:application:name: data-multidatasourcedatasource:type: com.zaxxer.hikari.HikariDataSourceurl: jdbc:mysql://localhost:3306/testusername: sapassword: ****second-datasource:driver-class-name: org.hsqldb.jdbc.JDBCDriverurl: jdbc:hsqldb:mem:db2username: sapassword:****1.2 自定義DataSource配置
@Configuration public class SencondDataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource newDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "secondDatasource") @ConfigurationProperties(prefix = "spring.second-datasource")public DataSource secondDataSource() {return DataSourceBuilder.create().build();} }3.工作原理
?spring boot的auto-configuration最具魔力的地方是@EnableAutoConfiguration注解
?通常注解application應用使用@SpringBootApplication或者如下自定義的方式:
@Configuration@EnableAutoConfiguration@ComponentScanpublic class Application{}@EnableAutoConfiguration注解開啟了spring ApplicationContext的自動配置功能,
它通過掃描classpath下的組件,滿足不同Conditions的bean注冊到容器中。
spring boot提供了不同的AutoConfiguration實現類,這些類都在spring-boot-autoconfigure-{version}.jar中,用來注冊各種各樣的組件。
通常,當AutoConfiguration實現類打上@Configuration標簽,可以作為spring配置類,當AutoConfiguration實現類打上@EnableConfigurationProperties標簽,可以綁定自定義屬性或者更多Conditional bean注冊方法。
下面就org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration來分析一下:
/*** {@link EnableAutoConfiguration Auto-configuration} for {@link DataSource}.** @author Dave Syer* @author Phillip Webb* @author Stephane Nicoll* @author Kazuki Shimizu*/ @Configuration @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) @EnableConfigurationProperties(DataSourceProperties.class) @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class }) public class DataSourceAutoConfiguration {private static final Log logger = LogFactory.getLog(DataSourceAutoConfiguration.class);@Bean@ConditionalOnMissingBeanpublic DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,ApplicationContext applicationContext) {return new DataSourceInitializer(properties, applicationContext);}/*** Determines if the {@code dataSource} being used by Spring was created from* {@link EmbeddedDataSourceConfiguration}.* @param beanFactory the bean factory* @return true if the data source was auto-configured.*/public static boolean containsAutoConfiguredDataSource(ConfigurableListableBeanFactory beanFactory) {try {BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSource");return EmbeddedDataSourceConfiguration.class.getName().equals(beanDefinition.getFactoryBeanName());}catch (NoSuchBeanDefinitionException ex) {return false;}}@Conditional(EmbeddedDatabaseCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import(EmbeddedDataSourceConfiguration.class)protected static class EmbeddedDatabaseConfiguration {}@Configuration@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class })protected static class PooledDataSourceConfiguration {}@Configuration@ConditionalOnProperty(prefix = "spring.datasource", name = "jmx-enabled")@ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy")@Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)@ConditionalOnMissingBean(name = "dataSourceMBean")protected static class TomcatDataSourceJmxConfiguration {@Beanpublic Object dataSourceMBean(DataSource dataSource) {if (dataSource instanceof DataSourceProxy) {try {return ((DataSourceProxy) dataSource).createPool().getJmxPool();}catch (SQLException ex) {logger.warn("Cannot expose DataSource to JMX (could not connect)");}}return null;}}/*** {@link AnyNestedCondition} that checks that either {@code spring.datasource.type}* is set or {@link PooledDataSourceAvailableCondition} applies.*/static class PooledDataSourceCondition extends AnyNestedCondition {PooledDataSourceCondition() {super(ConfigurationPhase.PARSE_CONFIGURATION);}@ConditionalOnProperty(prefix = "spring.datasource", name = "type")static class ExplicitType {}@Conditional(PooledDataSourceAvailableCondition.class)static class PooledDataSourceAvailable {}}/*** {@link Condition} to test if a supported connection pool is available.*/static class PooledDataSourceAvailableCondition extends SpringBootCondition {@Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context,AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition("PooledDataSource");if (getDataSourceClassLoader(context) != null) {return ConditionOutcome.match(message.foundExactly("supported DataSource"));}return ConditionOutcome.noMatch(message.didNotFind("supported DataSource").atAll());}/*** Returns the class loader for the {@link DataSource} class. Used to ensure that* the driver class can actually be loaded by the data source.* @param context the condition context* @return the class loader*/private ClassLoader getDataSourceClassLoader(ConditionContext context) {Class<?> dataSourceClass = new DataSourceBuilder(context.getClassLoader()).findType();return (dataSourceClass == null ? null : dataSourceClass.getClassLoader());}}/*** {@link Condition} to detect when an embedded {@link DataSource} type can be used.* If a pooled {@link DataSource} is available, it will always be preferred to an* {@code EmbeddedDatabase}.*/static class EmbeddedDatabaseCondition extends SpringBootCondition {private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();@Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context,AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition("EmbeddedDataSource");if (anyMatches(context, metadata, this.pooledCondition)) {return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));}EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();if (type == null) {return ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll());}return ConditionOutcome.match(message.found("embedded database").items(type));}}/*** {@link Condition} to detect when a {@link DataSource} is available (either because* the user provided one or because one will be auto-configured).*/@Order(Ordered.LOWEST_PRECEDENCE - 10)static class DataSourceAvailableCondition extends SpringBootCondition {private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();private final SpringBootCondition embeddedCondition = new EmbeddedDatabaseCondition();@Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context,AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition("DataSourceAvailable");if (hasBean(context, DataSource.class)|| hasBean(context, XADataSource.class)) {return ConditionOutcome.match(message.foundExactly("existing data source bean"));}if (anyMatches(context, metadata, this.pooledCondition,this.embeddedCondition)) {return ConditionOutcome.match(message.foundExactly("existing auto-configured data source bean"));}return ConditionOutcome.noMatch(message.didNotFind("any existing data source bean").atAll());}private boolean hasBean(ConditionContext context, Class<?> type) {return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getBeanFactory(), type, true, false).length > 0;}}}從上面看到,
1. DataSourceAutoConfiguration打上了@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })標簽,這意味著只有當DataSource.class和EmbeddedDatabaseType.class出現在classpath時,DataSourceAutoConfiguration內的自動配置bean才可能被注冊。
2.?DataSourceAutoConfiguration打上了@EnableConfigurationProperties(DataSourceProperties.class)標簽,意味著application.properties中的屬性和DataSourceProperties類自動綁定了。
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)public class DataSourceProperties implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {public static final String PREFIX = "spring.datasource";......private String driverClassName;private String url;private String username;private String password;...//setters and getters }上面的配置類中說明,在application.properties中以spring.datasource開頭的屬性將自動綁定到DataSourceProperties對象上。其他注解,如@ConditionalOnMissingBean, @ConditionalOnClass and @ConditionalOnProperty等,標識只要條件滿足,bean definition將注冊到ApplicationContext中。
參考文件:
【1】http://www.liaoxuefeng.com/article/001484212576147b1f07dc0ab9147a1a97662a0bd270c20000
【2】https://dzone.com/articles/how-springboot-autoconfiguration-magic-works
?
轉載于:https://www.cnblogs.com/davidwang456/p/6600550.html
總結
以上是生活随笔為你收集整理的spring boot自动配置之jdbc的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HikariCP--一款高性能的 JDB
- 下一篇: Spring Boot AutoConf