Spring BeanCreationException

Spring BeanCreationException

1. Visão geral

Neste artigo, estamos discutindo oSpring org.springframework.beans.factory.BeanCreationException - esta é uma exceção muito comum lançada quando oBeanFactory cria beans das definições de bean e encontra um problema. O artigo discutirá as causas mais comuns dessa exceção, juntamente com a solução.

Leitura adicional:

Introdução à Inversão do Controle e Injeção de Dependência com Mola

Uma rápida introdução aos conceitos de Inversão de Controle e Injeção de Dependência, seguida de uma demonstração simples usando o Spring Framework

Read more

Interfaces BeanNameAware e BeanFactoryAware na primavera

Dê uma olhada no trabalho com as interfaces BeanNameAware e BeanFactoryAware no Spring.

Read more

Registro do Bean Funcional da Primavera 5

Veja como registrar beans usando a abordagem funcional no Spring 5.

Read more

2. Causa:org.springframework.beans.factory.NoSuchBeanDefinitionException

De longe, a causa mais comum deBeanCreationException é o Spring tentandoinject a bean that doesn’t exist no contexto.

Por exemplo,BeanA está tentando injetarBeanB:

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

Se aBeanB não for encontrado no contexto, a seguinte exceção será lançada (Erro ao criar o bean):

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.BeanB org.example.web.BeanA.dependency;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.example.web.BeanB] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Para diagnosticar esse tipo de problema - primeiro, verifique se o bean está declarado:

  • em um arquivo de configuração XML usando o elemento<bean />

  • ou em uma classe Java@Configuration por meio da anotação@Bean

  • ou é anotado com:@Component,@Repository,@Service,@Controllere a varredura de caminho de classe está ativa para esse pacote

Verifique também se os arquivos ou classes de configuração são realmente selecionados pelo Spring e carregados no contexto principal.

Leitura adicional:

Introdução à Inversão do Controle e Injeção de Dependência com Mola

Uma rápida introdução aos conceitos de Inversão de Controle e Injeção de Dependência, seguida de uma demonstração simples usando o Spring Framework

Read more

Interfaces BeanNameAware e BeanFactoryAware na primavera

Dê uma olhada no trabalho com as interfaces BeanNameAware e BeanFactoryAware no Spring.

Read more

Registro do Bean Funcional da Primavera 5

Veja como registrar beans usando a abordagem funcional no Spring 5.

Read more

3. Causa:org.springframework.beans.factory.NoUniqueBeanDefinitionException

Outra causa semelhante para a exceção de criação de bean é o Spring tentando injetar um bean por tipo - ou seja, por sua interface - e encontrandotwo or more bean implementing that interface no contexto.

Por exemplo,BeanB1 eBeanB2 implementam a mesma interface:

@Component
public class BeanB1 implements IBeanB { ... }
@Component
public class BeanB2 implements IBeanB { ... }

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

Isso fará com que a seguinte exceção seja lançada pela fábrica de feijão Spring:

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.IBeanB org.example.web.BeanA.b;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [org.example.web.IBeanB] is defined:
expected single matching bean but found 2: beanB1,beanB2

4. Causa:org.springframework.beans.BeanInstantiationException

4.1. Exceção personalizada

O próximo na linha é umbean that throws an exception during its creation process; uma amostra simplificada para exemplificar e compreender facilmente o problema está lançando uma exceção no construtor do bean:

@Component
public class BeanA {

    public BeanA() {
        super();
        throw new NullPointerException();
    }
    ...
}

Como esperado, isso fará com que o Spring falhe rapidamente, com a seguinte exceção:

Error creating bean with name 'beanA' defined in file [...BeanA.class]:
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
Constructor threw exception;
nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Outra possível ocorrência deBeanInstantiationException é definir uma classe abstrata como um bean em XML; isso tem que ser em XML, porque não há como fazer isso em um arquivo Java @Configuration e a varredura do classpath irá ignorar a classe abstrata:

@Component
public abstract class BeanA implements IBeanA { ... }

E a definição XML do bean:

Essa configuração resultará em uma exceção semelhante:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanA' defined in class path resource [beansInXml.xml]:
Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
Is it an abstract class?;
nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Se um bean não tiver construtor padrão e o Spring tentar instancia-lo procurando por esse construtor, isso resultará em uma exceção de tempo de execução; por exemplo:

@Component
public class BeanA implements IBeanA {

    public BeanA(final String name) {
        super();
        System.out.println(name);
    }
}

Quando esse bean é capturado pelo mecanismo de verificação do caminho de classe, a falha será:

Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
No default constructor found;
nested exception is java.lang.NoSuchMethodException: org.example.web.BeanA.()

Uma exceção semelhante, mas mais difícil de diagnosticar, pode ocorrer quando as dependências do Spring no classpath não têmsame version; este tipo de incompatibilidade de versão pode resultar emNoSuchMethodException devido a alterações de API. A solução para esse problema é garantir que todas as bibliotecas Spring tenham exatamente a mesma versão no projeto.

5. Causa:org.springframework.beans.NotWritablePropertyException

Outra possibilidade é definir um bean -BeanA - com uma referência a outro bean -BeanB - sem ter o método setter correspondente emBeanA:

@Component
public class BeanA {
    private IBeanB dependency;
    ...
}
@Component
public class BeanB implements IBeanB { ... }

E a configuração XML da primavera:


    

Novamente, estecan only occur in XML Configuration, porque ao usar Java@Configuration, o compilador tornará este problema impossível de reproduzir.

Claro, para resolver esse problema, o setter precisa ser adicionado paraIBeanB:

@Component
public class BeanA {
    private IBeanB dependency;

    public void setDependency(final IBeanB dependency) {
        this.dependency = dependency;
    }
}

6. Causa:org.springframework.beans.factory.CannotLoadBeanClassException

Essa exceção é lançada quandoSpring cannot load the class of the defined bean - isso pode ocorrer se a configuração Spring XML contiver um bean que simplesmente não possui uma classe correspondente. Por exemplo, se a classeBeanZ não existir, a seguinte definição resultará em uma exceção:

A causa raiz seClassNotFoundExceptione a exceção completa neste caso for:

nested exception is org.springframework.beans.factory.BeanCreationException:
...
nested exception is org.springframework.beans.factory.CannotLoadBeanClassException:
Cannot find class [org.example.web.BeanZ] for bean with name 'beanZ'
defined in class path resource [beansInXml.xml];
nested exception is java.lang.ClassNotFoundException: org.example.web.BeanZ

7. Filhos deBeanCreationException

7.1. Oorg.springframework.beans.factory.BeanCurrentlyInCreationException

Uma das subclasses deBeanCreationException éBeanCurrentlyInCreationException; isso geralmente ocorre ao usar injeção de construtor - por exemplo, em um caso de dependências circulares:

@Component
public class BeanA implements IBeanA {
    private IBeanB beanB;

    @Autowired
    public BeanA(final IBeanB beanB) {
        super();
        this.beanB = beanB;
    }
}
@Component
public class BeanB implements IBeanB {
    final IBeanA beanA;

    @Autowired
    public BeanB(final IBeanA beanA) {
        super();
        this.beanA = beanA;
    }
}

O Spring não poderá resolver esse tipo de cenário de fiação e o resultado final será:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?

A exceção completa é muito detalhada:

org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'beanA' defined in file [...BeanA.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanB]: :
Error creating bean with name 'beanB' defined in file [...BeanB.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanA]: :
Error creating bean with name 'beanA': Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'beanB' defined in file [...BeanB.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanA]: :
Error creating bean with name 'beanA':
Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?

7.2. Oorg.springframework.beans.factory.BeanIsAbstractException

Essa exceção de instanciação pode ocorrer quando o Bean Factory tenta recuperar e instanciar um bean que foi declarado como abstrato; por exemplo:

public abstract class BeanA implements IBeanA {
   ...
}

Declarado na configuração XML como:

Agora, se tentarmosretrieve BeanA from the Spring Context by name - por exemplo, ao instanciar outro bean:

@Configuration
public class Config {
    @Autowired
    BeanFactory beanFactory;

    @Bean
    public BeanB beanB() {
        beanFactory.getBean("beanA");
        return new BeanB();
    }
}

Isso resultará na seguinte exceção:

org.springframework.beans.factory.BeanIsAbstractException:
Error creating bean with name 'beanA': Bean definition is abstract

E o stacktrace de exceção completo:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanB' defined in class path resource
[org/example/spring/config/WebConfig.class]: Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method
[public org.example.web.BeanB org.example.spring.config.WebConfig.beanB()] threw exception;
nested exception is org.springframework.beans.factory.BeanIsAbstractException:
Error creating bean with name 'beanA': Bean definition is abstract

8. Conclusão

No final deste artigo, devemos ter um mapa claro para navegar pela variedade de causas e problemas que podem levar aBeanCreationException no Spring, bem como uma boa compreensão de como consertar todos esses problemas.

A implementação de todos os exemplos de exceções pode ser encontrada emthe github project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.