Configurando uma fonte de dados programaticamente na inicialização do Spring

Configurando uma fonte de dados programaticamente na inicialização do Spring

1. Visão geral

Spring Boot usa um algoritmo opinativo para procurar e configurar umDataSource. Isso nos permite obter facilmente uma implementaçãoDataSource totalmente configurada por padrão.

Além disso, o Spring Boot configura automaticamente umconnection pool ultrarrápido -HikariCP,Apache Tomcat ouCommons DBCP, nessa ordem, dependendo de quais estão no caminho de classe.

While Spring Boot’s automatic DataSource configuration works very well in most cases, sometimes we’ll need a higher level of control, então teremos que configurar nossa própria implementaçãoDataSource, pulando assim o processo de configuração automática.

Neste tutorial, aprenderemoshow to configure a DataSource programmatically in Spring Boot.

Leitura adicional:

Spring JPA - vários bancos de dados

Como configurar o Spring Data JPA para trabalhar com vários bancos de dados separados.

Read more

Configurando o DataSource separado da Spring para testes

Um tutorial rápido e prático sobre como configurar uma fonte de dados separada para teste em um aplicativo Spring.

Read more

2. As dependências do Maven

Creating a DataSource implementation programmatically is straightforward, overall.

Para aprender como fazer isso, implementaremos uma camada de repositório simples, que realizará operações CRUD em algumas entidadesJPA.

Vamos dar uma olhada nas dependências do nosso projeto de demonstração:


    org.springframework.boot
    spring-boot-starter-data-jpa


    com.h2database
    h2
    2.4.1
    runtime

Conforme mostrado acima, usaremos uma instânciaH2 database na memória para exercitar a camada de repositório. Ao fazer isso, seremos capazes de testar nossoDataSource, configurado programaticamente sem o custo de realizar operações caras de banco de dados.

Além disso, vamos verificar a versão mais recente despring-boot-starter-data-jpa no Maven Central.

3. Configurando umDataSource programaticamente

Agora, se ficarmos com a configuração automáticaDataSource do Spring Boot e executarmos nosso projeto em seu estado atual, ele funcionará como esperado.

Spring Boot will do all the heavy infrastructure plumbing for us. Isso inclui a criação de uma implementação H2DataSource, que será tratada automaticamente pelo HikariCP, Apache Tomcat ou Commons DBCP, e a configuração de uma instância de banco de dados na memória.

Além disso, nem mesmo precisaremos criar um arquivoapplication.properties, pois o Spring Boot também fornecerá algumas configurações de banco de dados padrão.

Como mencionamos antes, às vezes precisaremos de um nível mais alto de personalização, portanto, teremos que configurar programaticamente nossa própria implementação deDataSource.

The simplest way to accomplish this is by defining a DataSource factory method, and placing it within a class annotated with the @Configuration annotation:

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

Nesse caso,we used the convenience DataSourceBuilder class - uma versão não fluente deJoshua Bloch’s builder pattern -to create programmatically our custom DataSource object.

Essa abordagem é muito boa porque o construtor facilita a configuração deDataSource usando algumas propriedades comuns. Além disso, ele também usa o pool de conexões subjacente.

4. Externalizando a configuração deDataSource com o arquivoapplication.properties

Claro, também é possível externalizar parcialmente nossa configuração deDataSource. Por exemplo, poderíamos definir algumas propriedades básicasDataSource em nosso método de fábrica:

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

E especifique alguns adicionais no arquivoapplication.properties:

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

As propriedades definidas em uma fonte externa, como o arquivoapplication.properties acima ou por meio de uma classe anotada com@ConfigurationProperties, substituirão as definidas na API Java.

Torna-se evidente que, com essa abordagem, não vamos mais manter nossas configurações deDataSource armazenadas em um único lugar.

Por outro lado, permite manter as definições de configuração em tempo de compilação e tempo de execução bem separadas uma da outra.

Isso é muito bom, pois permite definir facilmente um ponto de ligação da configuração. Dessa forma, podemos incluir configurações deDataSource diferentes de outras fontes, sem ter que refatorar nossos métodos de fábrica de bean.

5. Testando a configuração deDataSource

Testar nossa configuraçãoDataSource personalizada é muito simples. Todo o processo se resume em criar uma entidadeJPA, definir uma interface de repositório básica e testar a camada de repositório.

5.1. Criação de uma entidade JPA

Vamos começar a definir nossa classe de entidade de amostra JPA, que modelará usuários:

@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. Uma Camada de Repositório Simples

Em seguida, precisamos implementar uma camada de repositório básica, que nos permite realizar operações CRUD em instâncias da classe de entidadeUser definida acima.

Como estamos usandoSpring Data JPA, não precisamos criar nossa própria implementaçãoDAO do zero. Simplesmente temos que estender a interfaceCrudRepository para obter uma implementação de repositório funcional:

@Repository
public interface UserRepository extends CrudRepository {}

5.3. Testando a Camada de Repositório

Por último, precisamos verificar se nossoDataSource configurado programaticamente está realmente funcionando. Podemos facilmente fazer isso com um teste de integração:

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

A classeUserRepositoryIntegrationTest é bastante autoexplicativa. Ele simplesmente exercita dois dos métodos CRUD da interface do repositório para persistir e encontrar entidades.

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. Executando o aplicativo de amostra

Finalmente, podemos executar nosso aplicativo de demonstração usando um métodomain() padrão:

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

Já testamos a camada de repositório, então temos certeza de que nossoDataSource foi configurado com sucesso. Portanto, se executarmos o aplicativo de amostra, devemos ver na saída do console a lista de entidadesUser armazenadas no banco de dados.

6. Conclusão

Neste tutorial,we learned how to configure a DataSource implementation programmatically in Spring Boot.

Como de costume, todos os exemplos de código mostrados neste tutorial estão disponíveisover on GitHub.