Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Usar interface sem instanciar uma classe que a implementa

Opa pessoal, tudo bem?

Gostaria de entender melhor o funcionamento da interface no geral, através do exemplo da interface CrudRepository.

No projeto dessa aula criamos uma interface CargoRepository que extende de outra interface CrudRepository, conforme código abaixo:

@Repository
public interface CargoRepository extends CrudRepository<Cargo,Integer> {
}

Na classe CrudCargoService, em nenhum momento foi implementada a interface CargoRepository, e também não foi instaciada(que é um conceito que já compreendi que as interfaces "não podem" ser instaciadas). No código há apenas o atributo CargoRepository que é passado no construtor da Classe CrudCargoService, conforme abaixo:

    private final CargoRepository cargoRepository;

    public CrudCargoService(CargoRepository cargoRepository) {
        this.cargoRepository = cargoRepository;
    }

Minha dúvida é: como o Java faz para que essa classe CrudCargoService utilize os métodos da interface sem implementá-la? O Java meio que "cria uma instância" dessa interface por baixo dos panos ao fazer a injeção de depências no construtor? Alguém poderia me ajudar a compreender melhor isso?

Desde já agraço. Forte Abraço a todos

2 respostas
solução!

Olá, boa noite! Como as classes repository tem como único objetivo fazer as operações com o Banco de Dados, o Spring só precisa converter os nomes dos métodos dos repository em queries SQL:

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

// Somente alguns métodos da classe CrudRepository

        // Método é convertido no comando SQL INSERT INTO
        <S extends T> S save(S entity);

        // Comando SQL DELETE
        void delete(T entity);

        // Comando SELECT
        Optional<T> findById(ID id);
}

É possível também criar queries personalizadas só através do nome do método:

public interface UsuarioRepository extends JpaRepository<Usuario, Long> {

    public Optional<Usuario> findByEmail(String email);
    // Query SQL: SELECT u FROM Usuario u WHERE u.email = ?1 (Primeira variável passada como parâmetro)

}

Depois de converter os nomes dos métodos em Queries, o Spring as executa usando outras classes que são responsáveis por fazer as conexões com o Banco de Dados, como o EntityManager, DataSource e TransactionManager, então não é necessário criar objetos que implementem as interfaces Repository, mas apenas executar as queries e os outros comandos SQL. Qualquer coisa, dá uma olhada na documentação do Spring: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference. Espero ter ajudado!

Muito obrigado pela ajuda, Breno!