@@ -1690,99 +1690,175 @@ a| `log4j2.json` +
1690
1690
1691
1691
1692
1692
[[howto-configure-a-datasource]]
1693
- === Configure a DataSource
1694
- To override the default settings just define a `@Bean` of your own of type `DataSource`.
1695
- As explained in
1696
- <<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>> you
1697
- can easily bind it to a set of `Environment` properties:
1693
+ === Configure a custom DataSource
1694
+ To configure your own `DataSource` define a `@Bean` of that type in your configuration.
1695
+ Spring Boot will reuse your `DataSource` anywhere one is required, including database
1696
+ initialization. If you need to externalize some settings, you can easily bind your
1697
+ `DataSource` to the environment (see
1698
+ <<spring-boot-features.adoc#boot-features-external-config-3rd-party-configuration>>).
1698
1699
1699
1700
[source,java,indent=0,subs="verbatim,quotes,attributes"]
1700
1701
----
1701
1702
@Bean
1702
- @ConfigurationProperties(prefix="datasource.fancy ")
1703
+ @ConfigurationProperties(prefix="app.datasource ")
1703
1704
public DataSource dataSource() {
1704
1705
return new FancyDataSource();
1705
1706
}
1706
1707
----
1707
1708
1708
1709
[source,properties,indent=0]
1709
1710
----
1710
- datasource.fancy.jdbcUrl =jdbc:h2:mem:mydb
1711
- datasource.fancy .username=sa
1712
- datasource.fancy.poolSize =30
1711
+ app. datasource.url =jdbc:h2:mem:mydb
1712
+ app.datasource .username=sa
1713
+ app. datasource.pool-size =30
1713
1714
----
1714
1715
1715
- Spring Boot also provides a utility builder class `DataSourceBuilder` that can be used
1716
- to create one of the standard data sources (if it is on the classpath), or you can just
1717
- create your own. If you want to reuse the customizations of `DataSourceProperties`, you
1718
- can easily initialize a `DataSourceBuilder` from it:
1716
+ Assuming that your `FancyDataSource` has regular JavaBean properties for the url, the
1717
+ username and the pool size, these settings will be bound automatically before the
1718
+ `DataSource` is made available to other components. The regular
1719
+ <<howto-initialize-a-database-using-spring-jdbc,database initialization>> will also happen
1720
+ (so the relevant sub-set of `spring.datasource.*` can still be used with your custom
1721
+ configuration).
1722
+
1723
+ You can apply the same principle if you are configuring a custom JNDI `DataSource`:
1719
1724
1720
1725
[source,java,indent=0,subs="verbatim,quotes,attributes"]
1721
1726
----
1722
- @Bean
1723
- @ConfigurationProperties(prefix="datasource.mine")
1724
- public DataSource dataSource(DataSourceProperties properties) {
1725
- return properties.initializeDataSourceBuilder()
1726
- // additional customizations
1727
- .build();
1727
+ @Bean(destroyMethod="")
1728
+ @ConfigurationProperties(prefix="app.datasource")
1729
+ public DataSource dataSource() throws Exception {
1730
+ JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
1731
+ return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
1728
1732
}
1729
1733
----
1730
1734
1735
+
1736
+ Spring Boot also provides a utility builder class `DataSourceBuilder` that can be used
1737
+ to create one of the standard data sources (if it is on the classpath). The builder can
1738
+ detect the one to use based on the ones available on the classpath and it also auto
1739
+ detects the driver based on the JDBC url.
1740
+
1741
+ [source,java,indent=0,subs="verbatim,quotes,attributes"]
1742
+ ----
1743
+ include::{code-examples}/jdbc/BasicDataSourceExample.java[tag=configuration]
1744
+ ----
1745
+
1746
+ To run an app with that `DataSource`, all that is needed really is the connection
1747
+ information; pool-specific settings can also be provided, check the implementation that
1748
+ is going to be used at runtime for more details.
1749
+
1750
+ [source,properties,indent=0]
1751
+ ----
1752
+ app.datasource.url=jdbc:mysql://localhost/test
1753
+ app.datasource.username=dbuser
1754
+ app.datasource.password=dbpass
1755
+ app.datasource.pool-size=30
1756
+ ----
1757
+
1758
+ There is a catch however. Because the actual type of the connection pool is not exposed,
1759
+ no keys are generated in the metadata for your custom `DataSource` and no completion is
1760
+ available in your IDE (The `DataSource` interface doesn't expose any property). Also, if
1761
+ you happen to _only_ have Hikari on the classpath, this basic setup will not work because
1762
+ Hikari has no `url` parameter (but a `jdbcUrl` parameter). You should have to rewrite
1763
+ your configuration as follows:
1764
+
1765
+ [source,properties,indent=0]
1766
+ ----
1767
+ app.datasource.jdbc-url=jdbc:mysql://localhost/test
1768
+ app.datasource.username=dbuser
1769
+ app.datasource.password=dbpass
1770
+ app.datasource.maximum-pool-size=30
1771
+ ----
1772
+
1773
+ You can fix that by forcing the connection pool to use and return a dedicated
1774
+ implementation rather than `DataSource`. You won't be able to change the implementation
1775
+ at runtime but the list of options will be explicit.
1776
+
1777
+ [source,java,indent=0,subs="verbatim,quotes,attributes"]
1778
+ ----
1779
+ include::{code-examples}/jdbc/SimpleDataSourceExample.java[tag=configuration]
1780
+ ----
1781
+
1782
+ You can even go further by leveraging what `DataSourceProperties` does for you, that is
1783
+ providing a default embedded database if no url is provided with a sensible username and
1784
+ password for it. You can easily initialize a `DataSourceBuilder` from the state of any
1785
+ `DataSourceProperties` so you could just as well inject the one Spring Boot creates
1786
+ automatically. However, that would split your configuration in two namespaces: url,
1787
+ username, password, type and driver on `spring.datasource` and the rest on your custom
1788
+ namespace (`app.datasource`). To avoid that, you can redefine a custom
1789
+ `DataSourceProperties` on your custom namespace:
1790
+
1791
+ [source,java,indent=0,subs="verbatim,quotes,attributes"]
1792
+ ----
1793
+ include::{code-examples}/jdbc/ConfigurableDataSourceExample.java[tag=configuration]
1794
+ ----
1795
+
1796
+ This setup puts you _in pair_ with what Spring Boot does for you by default, except that
1797
+ a dedicated connection pool is chosen (in code) and its settings are exposed in the same
1798
+ namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl`
1799
+ translation for you, you can configure it like this:
1800
+
1731
1801
[source,properties,indent=0]
1732
1802
----
1733
- spring.datasource.url=jdbc:h2:mem:mydb
1734
- spring.datasource.username=sa
1735
- datasource.mine.poolSize=30
1803
+ app.datasource.url=jdbc:mysql://localhost/test
1804
+ app.datasource.username=dbuser
1805
+ app.datasource.password=dbpass
1806
+ app.datasource.maximum-pool-size=30
1736
1807
----
1737
1808
1738
- In this scenario, you keep the standard properties exposed by Spring Boot with your
1739
- custom `DataSource` arrangement. By adding `@ConfigurationProperties`, you can also
1740
- expose additional implementation-specific settings in a dedicated namespace .
1809
+ NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type`
1810
+ will have no effect. In practice the builder will be initialized with whatever value you
1811
+ might set there and then overridden by the call to `.type()`` .
1741
1812
1742
1813
See _<<spring-boot-features.adoc#boot-features-configure-datasource>>_ in the
1743
1814
'`Spring Boot features`' section and the
1744
1815
{sc-spring-boot-autoconfigure}/jdbc/DataSourceAutoConfiguration.{sc-ext}[`DataSourceAutoConfiguration`]
1745
1816
class for more details.
1746
1817
1747
- [TIP]
1748
- ====
1749
- You could also do that if you want to configure a JNDI data-source.
1818
+
1819
+
1820
+ [[howto-two-datasources]]
1821
+ === Configure Two DataSources
1822
+ If you need to configure multiple data sources, you can apply the same tricks that are
1823
+ described in the previous section. You must, however, mark one of the `DataSource`
1824
+ `@Primary` as various auto-configurations down the road expect to be able to get one by
1825
+ type.
1826
+
1827
+ If you create your own `DataSource`, the auto-configuration will back off. In the example
1828
+ below, we provide the _exact_ same features set than what the auto-configuration provides
1829
+ on the primary data source:
1750
1830
1751
1831
[source,java,indent=0,subs="verbatim,quotes,attributes"]
1752
1832
----
1753
- @Bean(destroyMethod="")
1754
- @ConfigurationProperties(prefix="datasource.mine")
1755
- public DataSource dataSource() throws Exception {
1756
- JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
1757
- return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
1758
- }
1833
+ include::{code-examples}/jdbc/SimpleTwoDataSourcesExample.java[tag=configuration]
1759
1834
----
1760
- ====
1761
1835
1836
+ TIP: `fooDataSourceProperties` has to be flagged `@Primary` so that the database
1837
+ initializer feature uses your copy (should you use that).
1762
1838
1839
+ Both data sources are also bound for advanced customizations. For instance you could
1840
+ configure them as follows:
1763
1841
1764
- [[howto-two-datasources]]
1765
- === Configure Two DataSources
1766
- Creating more than one data source works the same as creating the first one. You might
1767
- want to mark one of them as `@Primary` if you are using the default auto-configuration for
1768
- JDBC or JPA (then that one will be picked up by any `@Autowired` injections).
1842
+ [source,properties,indent=0]
1843
+ ----
1844
+ app.datasource.foo.type=com.zaxxer.hikari.HikariDataSource
1845
+ app.datasource.foo.maximum-pool-size=30
1769
1846
1770
- [source,java,indent=0,subs="verbatim,quotes,attributes"]
1847
+ app.datasource.bar.url=jdbc:mysql://localhost/test
1848
+ app.datasource.bar.username=dbuser
1849
+ app.datasource.bar.password=dbpass
1850
+ app.datasource.bar.max-total=30
1771
1851
----
1772
- @Bean
1773
- @Primary
1774
- @ConfigurationProperties(prefix="datasource.primary")
1775
- public DataSource primaryDataSource() {
1776
- return DataSourceBuilder.create().build();
1777
- }
1778
1852
1779
- @Bean
1780
- @ConfigurationProperties(prefix="datasource.secondary")
1781
- public DataSource secondaryDataSource() {
1782
- return DataSourceBuilder.create().build();
1783
- }
1853
+ Of course, you can apply the same concept to the secondary `DataSource` as well:
1854
+
1855
+ [source,java,indent=0,subs="verbatim,quotes,attributes"]
1856
+ ----
1857
+ include::{code-examples}/jdbc/CompleteTwoDataSourcesExample.java[tag=configuration]
1784
1858
----
1785
1859
1860
+ This final example configures two data sources on custom namespaces with the same logic
1861
+ than what Spring Boot would do in auto-configuration.
1786
1862
1787
1863
1788
1864
[[howto-use-spring-data-repositories]]
0 commit comments