Програмно конфигуриране на DataSource в Spring Boot

1. Общ преглед

Spring Boot използва опитен алгоритъм за сканиране и конфигуриране на DataSource . Това ни позволява лесно да получим напълно конфигурирана реализация на DataSource по подразбиране.

Освен това Spring Boot автоматично конфигурира пул с бързи връзки - HikariCP, Apache Tomcat или Commons DBCP, в този ред, в зависимост от това кои са в пътя на класа.

Въпреки че автоматичната конфигурация на DataSource на Spring Boot работи много добре в повечето случаи, понякога ще се нуждаем от по-високо ниво на контрол , така че ще трябва да настроим нашето собствено изпълнение на DataSource , като по този начин ще пропуснем процеса на автоматично конфигуриране.

В този урок ще научим как да конфигурираме DataSource програмно в Spring Boot .

2. Зависимостите на Maven

Като цяло създаването на изпълнение на DataSource е лесно .

За да научим как да постигнем това, ще внедрим прост слой от хранилище, който ще изпълнява CRUD операции върху някои JPA обекти.

Нека да разгледаме зависимостите на нашия демо проект:

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

Както е показано по-горе, ще използваме екземпляр от база данни H2 в паметта, за да упражним слоя на хранилището. По този начин ще можем да тестваме нашия програмно конфигуриран DataSource, без разходи за извършване на скъпи операции с база данни.

В допълнение, нека не забравяме да проверим най-новата версия на spring-boot-starter-data-jpa в Maven Central.

3. Конфигуриране на DataSource програмно

Сега, ако се придържаме към автоматичната конфигурация на DataSource на Spring Boot и стартираме нашия проект в сегашното му състояние, той просто ще работи според очакванията.

Spring Boot ще направи всички тежки водопроводни инфраструктури за нас. Това включва създаване на внедряване на H2 DataSource , което автоматично ще се обработва от HikariCP, Apache Tomcat или Commons DBCP и настройка на екземпляр на база данни в паметта.

Освен това дори няма да е необходимо да създаваме файл application.properties , тъй като Spring Boot ще предостави и някои настройки по подразбиране на базата данни.

Както споменахме по-рано, понякога ще се нуждаем от по-високо ниво на персонализиране, поради което ще трябва да конфигурираме програмно нашето собствено изпълнение на DataSource .

Най-простият начин да постигнете това е чрез дефиниране на фабричен метод на DataSource и поставянето му в клас, коментиран с анотацията @Configuration :

@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(); } }

В този случай използвахме удобния клас DataSourceBuilder - непроменена версия на шаблона на конструктора на Joshua Bloch - за да създадем програмно нашия потребителски обект DataSource .

Този подход е наистина хубав, защото конструкторът улеснява конфигурирането на DataSource, използвайки някои често срещани свойства. Освен това той използва и основния пул за връзки.

4. Екстернализиране на конфигурацията на DataSource с файла application.properties

Разбира се, възможно е и частично да екстернализираме нашата конфигурация на DataSource . Например, можем да дефинираме някои основни свойства на DataSource в нашия фабричен метод:

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

И посочете няколко допълнителни във файла application.properties :

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

Свойствата, дефинирани във външен източник, като горния файл application.properties или чрез клас, анотиран с @ConfigurationProperties , ще заменят тези, дефинирани в Java API.

Става очевидно, че с този подход вече няма да съхраняваме настройките си за конфигуриране на DataSource на едно и също място .

От друга страна, това ни позволява да поддържаме настройките за време на компилация и време за изпълнение добре разделени една от друга.

Това е наистина добре, тъй като ни позволява лесно да зададем точка на свързване на конфигурацията. По този начин можем да включим различни настройки на DataSource от други източници, без да се налага да рефакторираме нашите фабрични методи за зърна.

5. Тестване на конфигурацията на DataSource

Тестването на нашата персонализирана конфигурация на DataSource е много просто. Целият процес се свежда до създаване на JPA обект, дефиниране на интерфейс на основното хранилище и тестване на слоя на хранилището.

5.1. Създаване на JPA обект

Нека започнем да дефинираме нашия примерен клас JPA обект, който ще моделира потребители:

@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. Прост слой на хранилището

След това трябва да внедрим основен слой на хранилището, който ни позволява да изпълняваме CRUD операции на екземпляри от потребителския клас обект, дефиниран по-горе.

Тъй като използваме Spring Data JPA, не е нужно да създаваме собствена реализация на DAO от нулата. Просто трябва да разширим интерфейса на CrudRepository, за да получим работещо изпълнение на хранилището:

@Repository public interface UserRepository extends CrudRepository {} 

5.3. Тестване на слоя на хранилището

И накрая, трябва да проверим дали нашият програмно конфигуриран DataSource действително работи. Лесно можем да постигнем това с тест за интеграция:

@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); } }

Класът UserRepositoryIntegrationTest е доста обяснителен. Той просто упражнява два от CRUD методите на интерфейса на хранилището, за да продължи и да намери обекти.

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

В този урок научихме как да конфигурираме внедряването на DataSource програмно в Spring Boot .

Както обикновено, всички примерни кодове, показани в този урок, са достъпни в GitHub.