Programmgesteuertes Konfigurieren einer DataSource im Spring Boot

1. Übersicht

Spring Boot verwendet einen meinungsgebundenen Algorithmus, um nach einer DataSource zu suchen und diese zu konfigurieren . Auf diese Weise können wir standardmäßig problemlos eine vollständig konfigurierte DataSource- Implementierung erhalten.

Darüber hinaus konfiguriert Spring Boot automatisch einen blitzschnellen Verbindungspool - entweder HikariCP, Apache Tomcat oder Commons DBCP - in dieser Reihenfolge, je nachdem, welche sich im Klassenpfad befinden.

Während die automatische DataSource- Konfiguration von Spring Boot in den meisten Fällen sehr gut funktioniert, benötigen wir manchmal ein höheres Maß an Kontrolle , sodass wir unsere eigene DataSource- Implementierung einrichten müssen, um den automatischen Konfigurationsprozess zu überspringen.

In diesem Tutorial erfahren Sie, wie Sie eine DataSource in Spring Boot programmgesteuert konfigurieren .

2. Die Maven-Abhängigkeiten

Das programmgesteuerte Erstellen einer DataSource- Implementierung ist insgesamt unkompliziert .

Um zu erfahren, wie dies erreicht werden kann, implementieren wir eine einfache Repository-Schicht, die CRUD-Operationen für einige JPA-Entitäten ausführt.

Werfen wir einen Blick auf die Abhängigkeiten unseres Demo-Projekts:

 org.springframework.boot spring-boot-starter-data-jpa   com.h2database h2 2.4.1 runtime 

Wie oben gezeigt, verwenden wir eine speicherinterne H2-Datenbankinstanz, um die Repository-Schicht auszuüben. Auf diese Weise können wir unsere programmgesteuert konfigurierte DataSource testen , ohne die Kosten für teure Datenbankoperationen zu tragen.

Überprüfen Sie außerdem die neueste Version von Spring-Boot-Starter-Data-JPA auf Maven Central.

3. Programmgesteuertes Konfigurieren einer DataSource

Wenn wir uns nun an die automatische DataSource- Konfiguration von Spring Boot halten und unser Projekt im aktuellen Zustand ausführen, funktioniert es wie erwartet.

Spring Boot wird die gesamte Infrastruktur für uns übernehmen. Dies umfasst das Erstellen einer H2 DataSource- Implementierung, die automatisch von HikariCP, Apache Tomcat oder Commons DBCP verarbeitet wird, und das Einrichten einer speicherinternen Datenbankinstanz.

Darüber hinaus müssen wir nicht einmal eine application.properties- Datei erstellen , da Spring Boot auch einige Standarddatenbankeinstellungen bereitstellt.

Wie bereits erwähnt, müssen wir manchmal einen höheren Grad an Anpassung vornehmen, daher müssen wir unsere eigene DataSource- Implementierung programmgesteuert konfigurieren .

Der einfachste Weg, dies zu erreichen, besteht darin, eine DataSource- Factory-Methode zu definieren und sie in eine Klasse zu platzieren, die mit der Annotation @Configuration versehen ist :

@Configuration public class DataSourceConfig { @Bean public DataSource getDataSource() { DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); dataSourceBuilder.driverClassName("org.h2.Driver"); dataSourceBuilder.url("jdbc:h2:mem:test"); dataSourceBuilder.username("SA"); dataSourceBuilder.password(""); return dataSourceBuilder.build(); } }

In diesem Fall haben wir die praktische DataSourceBuilder- Klasse verwendet - eine nicht fließende Version des Builder-Musters von Joshua Bloch - , um programmgesteuert unser benutzerdefiniertes DataSource- Objekt zu erstellen .

Dieser Ansatz ist sehr hilfreich, da der Builder das Konfigurieren einer DataSource mithilfe einiger allgemeiner Eigenschaften vereinfacht . Darüber hinaus wird auch der zugrunde liegende Verbindungspool verwendet.

4. Externalisierung der DataSource- Konfiguration mit der Datei application.properties

Natürlich ist es auch möglich, unsere DataSource- Konfiguration teilweise zu externalisieren . Zum Beispiel könnten wir einige grundlegende DataSource- Eigenschaften in unserer Factory-Methode definieren:

@Bean public DataSource getDataSource() { DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); dataSourceBuilder.username("SA"); dataSourceBuilder.password(""); return dataSourceBuilder.build(); }

Geben Sie in der Datei application.properties einige zusätzliche an :

spring.datasource.url=jdbc:h2:mem:test spring.datasource.driver-class-name=org.h2.Driver 

Die in einer externen Quelle definierten Eigenschaften, z. B. die obige Datei application.properties oder eine mit @ConfigurationProperties kommentierte Klasse , überschreiben die in der Java-API definierten Eigenschaften .

Es wird deutlich, dass wir mit diesem Ansatz unsere DataSource- Konfigurationseinstellungen nicht mehr an einem einzigen Ort speichern .

Auf der anderen Seite können wir die Einstellungen für die Kompilierungs- und Laufzeitkonfiguration gut voneinander trennen.

Dies ist wirklich gut, da wir auf einfache Weise einen Konfigurationsbindungspunkt festlegen können. Auf diese Weise können wir andere DataSource- Einstellungen aus anderen Quellen einbeziehen , ohne unsere Bean Factory-Methoden umgestalten zu müssen.

5. Testen der DataSource- Konfiguration

Das Testen unserer benutzerdefinierten DataSource- Konfiguration ist sehr einfach. Der gesamte Prozess läuft darauf hinaus, eine JPA-Entität zu erstellen, eine grundlegende Repository-Schnittstelle zu definieren und die Repository-Schicht zu testen.

5.1. Erstellen einer JPA-Entität

Beginnen wir mit der Definition unserer Beispiel-JPA-Entitätsklasse, die Benutzer modelliert:

@Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private String email; // standard constructors / setters / getters / toString }

5.2. Eine einfache Repository-Schicht

Als Nächstes müssen wir eine grundlegende Repository-Schicht implementieren, mit der wir CRUD-Operationen für Instanzen der oben definierten User- Entity-Klasse ausführen können .

Da wir Spring Data JPA verwenden, müssen wir keine eigene DAO-Implementierung von Grund auf neu erstellen. Wir müssen lediglich die CrudRepository- Schnittstelle erweitern, um eine funktionierende Repository-Implementierung zu erhalten:

@Repository public interface UserRepository extends CrudRepository {} 

5.3. Testen der Repository-Schicht

Zuletzt müssen wir überprüfen, ob unsere programmgesteuert konfigurierte DataSource tatsächlich funktioniert. Dies können wir leicht mit einem Integrationstest erreichen:

@RunWith(SpringRunner.class) @DataJpaTest public class UserRepositoryIntegrationTest { @Autowired private UserRepository userRepository; @Test public void whenCalledSave_thenCorrectNumberOfUsers() { userRepository.save(new User("Bob", "[email protected]")); List users = (List) userRepository.findAll(); assertThat(users.size()).isEqualTo(1); } }

Die UserRepositoryIntegrationTest- Klasse ist ziemlich selbsterklärend. Es werden lediglich zwei der CRUD-Methoden der Repository-Schnittstelle ausgeführt, um Entitäten beizubehalten und zu finden.

Notice that regardless of whether we decide to programmatically configure our DataSource implementation, or split it into a Java config method and the application.properties file, we should always get a working database connection.

5.4. Running the Sample Application

Finally, we can run our demo application using a standard main() method:

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner run(UserRepository userRepository) throws Exception { return (String[] args) -> { User user1 = new User("John", "[email protected]"); User user2 = new User("Julie", "[email protected]"); userRepository.save(user1); userRepository.save(user2); userRepository.findAll().forEach(user -> System.out.println(user); }; } } 

We already tested the repository layer, so we're sure that our DataSource has been configured successfully. Thus, if we run the sample application, we should see in our console output the list of User entities stored in the database.

6. Conclusion

In diesem Tutorial haben wir gelernt, wie Sie eine DataSource- Implementierung programmgesteuert in Spring Boot konfigurieren .

Wie üblich sind alle in diesem Tutorial gezeigten Codebeispiele auf GitHub verfügbar.