Dependência Insatisfeita na Primavera

Dependência Insatisfeita na Primavera

1. Visão geral

Neste tutorial rápido, explicaremosUnsatisfiedDependencyException do Spring, o que o causa e como evitá-lo.

2. Causa deUnsatisfiedDependencyException

UnsatisfiedDependencyException é lançado quando, como o nome sugere, algum bean ou dependência de propriedade não é satisfeita.

Isso pode acontecer quando o aplicativo Spring tenta conectar um bean e não pode resolver uma das dependências obrigatórias.

3. Exemplo de aplicação

Suponha que temos uma classe de serviçoPurchaseDeptService, que depende deInventoryRepository:

@Service
public class PurchaseDeptService {
    public PurchaseDeptService(InventoryRepository repository) {
        this.repository = repository;
    }
}
public interface InventoryRepository {
}
@Repository
public class ShoeRepository implements InventoryRepository {
}
@SpringBootApplication
public class SpringDependenciesExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDependenciesExampleApplication.class, args);
    }
}

Por enquanto, assumiremos que todas essas classes estão localizadas no mesmo pacote denominadocom.example.dependency.exception.app.

Quando executamos esse aplicativo Spring Boot, tudo funciona bem. Vamos ver em que tipo de problemas podemos encontrar se pularmos uma etapa de configuração.

4. Anotação de componente ausente

Agora, vamos remover a nota@Repository an da nossa classeShoeRepository:

public class ShoeRepository implements InventoryRepository {
}

Quando iniciarmos nosso aplicativo novamente, veremos a seguinte mensagem de erro:UnsatisfiedDependencyException: Error creating bean with name ‘purchaseDeptService': Unsatisfied dependency expressed through constructor parameter 0

O Spring não foi instruído a conectar um beanShoeRepository e adicioná-lo ao contexto do aplicativo, portanto, não pôde injetá-lo e lançou a exceção.

Adicionar a anotação@Repository de volta aoShoeRepository resolve o problema.

5. Pacote não verificado

Vamos agora colocar nossoShoeRepository (junto comInventoryRepository) em um pacote separado chamadocom.example.dependency.exception.repository.

Mais uma vez, quando executamos nosso aplicativo, ele lançaUnsatisfiedDependencyException. Para resolver isso, podemos configurar a verificação do pacote no pacote pai e garantir que todas as classes relevantes sejam incluídas:

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.dependency.exception"})
public class SpringDependenciesExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringDependenciesExampleApplication.class, args);
    }
}

6. Resolução de dependência não exclusiva

Suponha que adicionemos outra implementaçãoInventoryRepository -DressRepository:

@Repository
public class DressRepository implements InventoryRepository {
}

Agora, quando rodarmos nosso aplicativo, ele vai mais uma vez lançar oUnsatisfiedDependencyException.

No entanto, desta vez a situação é diferente. Na verdade, odependency cannot be resolved when there’s more than one bean that satisfies it.

Para resolver isso, podemos querer adicionar@Qualifier para distinguir entre os repositórios:

@Qualifier("dresses")
@Repository
public class DressRepository implements InventoryRepository {
}
@Qualifier("shoes")
@Repository
public class ShoeRepository implements InventoryRepository {
}

Além disso, teremos que adicionar um qualificador à dependência do construtorPurchaseDeptService:

public PurchaseDeptService(@Qualifier("dresses") InventoryRepository repository) {
    this.repository = repository;
}

Isso tornaráDressRepository a única opção viável, e o Spring irá injetá-lo emPurchaseDeptService.

7. Conclusão

Neste artigo, vimos vários casos mais comuns de encontrarUnsatisfiedDependencyException. . Além disso, aprendemos como resolver esses problemas.

Você também pode querer dar uma olhada no tutorial mais geral emSpring BeanCreationException.

O código apresentado aqui pode ser encontradoover on GitHub.