Pular para conteúdo

Injeção de Dependência e Camadas

A injeção de dependência fornece colaboradores externos a um objeto, em vez de permitir que ele os localize ou construa. A injeção por construtor torna as dependências obrigatórias explícitas e permite campos imutáveis.

@Service
final class BookService {
    private final BookRepository repository;
    private final Clock clock;

    BookService(BookRepository repository, Clock clock) {
        this.repository = repository;
        this.clock = clock;
    }
}

Injetar Clock torna o tempo uma dependência explícita e permite testes determinísticos. Evite usar o contêiner como localizador global de serviços.

Responsabilidades

Camada Responsabilidade típica
Transporte Parsing HTTP, representação, status e headers
Aplicação Orquestração de casos de uso e intenção transacional
Domínio Invariantes e decisões do negócio
Infraestrutura Persistência, mensageria e adaptadores remotos

Essas são responsabilidades, não uma exigência de quatro pacotes para toda operação. Um fluxo simples pode precisar de menos separação; um domínio complexo pode exigir limites mais fortes.

Portas e adaptadores

A aplicação pode depender de uma interface de repositório orientada ao domínio, enquanto um adaptador a implementa com JPA ou outro mecanismo. O benefício é a direção interna das dependências, que mantém a política testável e alterável.

Cuidados com o ciclo de vida dos beans

Beans singleton são compartilhados. Prefira colaboradores sem estado ou estado imutável. Evite campos mutáveis específicos de uma requisição em beans singleton. Saiba quando proxies fornecem comportamentos como transações, segurança de método, cache ou execução assíncrona; chamadas que contornam o proxy também podem contornar esse comportamento.

Configuração

Use @ConfigurationProperties para configurações externas coesas e com segurança de tipos. Use perfis para diferenças reais de ambiente ou grupos de recursos, não como substitutos de uma configuração bem definida.