본문 바로가기

Web/spring

[Spring Exception] Spring BeanCreationException

728x90

https://github.com/eugenp/tutorials/tree/master/spring-exceptions

 

GitHub - eugenp/tutorials: Just Announced - "Learn Spring Security OAuth":

Just Announced - "Learn Spring Security OAuth": . Contribute to eugenp/tutorials development by creating an account on GitHub.

github.com

 

여기 있는 tutorials 시리즈로 정리해볼 예정

 

https://www.baeldung.com/spring-beancreationexception

 


 Spring org.springframework.beans.factory.BeanCreationException

 

 BeanFactory 가 Bean 정의의 Bean을 생성하고 문제에 직면할 때 발생하는 매우 일반적인 예외처리이다.

 

 

Cause: org.springframework.beans.factory.NoSuchBeanDefinitionException

BeanCreationException 이 발생하는 일반적인 원인은 존재하지 않는 Bean을 주입하려고 할 때 이다

 

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

컨텍스트에서 BeanB  찾을 수 없으면 다음 예외가 발생한다(Error Creation 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 com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.baeldung.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)}

이러한 유형의 문제를 진단하기 위해 먼저 빈이 선언되었는지 확인해보면 된다

 

  • <bean /> 요소를 사용하는 XML 구성 파일에서
  • 또는 @Bean 주석을 통해 Java @Configuration 클래스에서
  • 또는 @Component , @Repository , @Service , @Controller 로 주석이 지정되고 해당 패키지에 대해 클래스 경로 스캐닝이 활성화됐는지

또한 Spring이 실제로 구성 파일이나 클래스를 선택하여 기본 컨텍스트에 로드하는지 확인해보면 된다

 

 


Cause: org.springframework.beans.factory.NoUniqueBeanDefinitionException

 

인터페이스별로 bean을 주입하려고 시도하고 컨텍스트에서 해당 인터페이스를 구현하는 두 개 이상의 bean을 찾는 것이다.

BeanB1  BeanB2 는 모두 동일한 인터페이스를 구현한다.

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

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

이로 인해 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 com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; 
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [com.baeldung.web.IBeanB] is defined: 
expected single matching bean but found 2: beanB1,beanB2

 

 


Cause: org.springframework.beans.BeanInstantiationException

Custom Exception

bean that throws an exception during its creation process

생성 프로세스 중에 예외를 처리하는 경우이다

@Component
public class BeanA {

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

예상대로 다음 예외와 함께 Spring이 실패된다.

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 [com.baeldung.web.BeanA]: 
Constructor threw exception; 
nested exception is java.lang.NullPointerException

 

 

 

java.lang.InstantiationException

BeanInstantiationException 의 또 다른 가능한 발생은 추상 클래스를 XML의 bean으로 정의하는 것이다.

@Configuration 파일 에서 수행할 수 있는 방법이 없기 때문에 XML에 있어야 하며 클래스 경로 스캔은 추상 클래스를 무시한다

 

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

빈의 XML 정의는 다음과 같습니다.

<bean id="beanA" class="com.baeldung.web.BeanA" />

이 설정으로 인해 유사한 예외가 발생합니다.

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 [com.baeldung.web.BeanA]: 
Is it an abstract class?; 
nested exception is java.lang.InstantiationException

 

 

java.lang.NoSuchMethodException

bean에 기본 생성자가 없고 Spring이 해당 생성자를 찾아 인스턴스화하려고 할때 런타임 예외가 발생한다

@Component
public class BeanA implements IBeanA {

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

클래스 경로 스캐닝 메커니즘이 이 빈을 선택하면 실패는 다음과 같게 나온다.

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 [com.baeldung.web.BeanA]: 
No default constructor found; 
nested exception is java.lang.NoSuchMethodException: com.baeldung.web.BeanA.<init>()복사

 

유사한 예외이지만 진단하기 더 어려운 경우는

클래스 경로의 Spring 종속성이 동일한 버전을 가지고 있지 않을 때이다. 

이러한 종류의 버전 비호환성으로 인해 API 변경으로 인해 NoSuchMethodException이 발생할 수 있다 . 

이러한 문제에 대한 해결책은 모든 Spring 라이브러리가 프로젝트에서 정확히 동일한 버전을 갖도록 하는 것이다.

 

 


Cause: org.springframework.beans.NotWritablePropertyException

BeanA에 해당하는 setter 메소드가 없는 다른 bean인 BeanB 에 대한 참조로 BeanA BeanA를 정의할때 나타난다

 

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

 

 

Spring XML 구성

<bean id="beanA" class="com.baeldung.web.BeanA">
    <property name="beanB" ref="beanB" />
</bean>

다시 말하지만 이것은 Java @Configuration 을  사용할 때 컴파일러가 이 문제를 재현할 수 없도록 만들기 때문에 XML 구성에서만 발생할 수 있다

 

예외 오류 해결 방법은 IBeanB 에 대한 setter를 추가하는 것이다

@Component
public class BeanA {
    private IBeanB dependency;

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

 

 

 

Cause: org.springframework.beans.factory.CannotLoadBeanClassException

 

Spring은 정의된 bean의 클래스를 로드할 수 없을 때 이 예외가 발생한다

BeanZ 클래스가 존재하지 않는 경우 다음 정의는 예외를 발생시킨다.

<bean id="beanZ" class="com.baeldung.web.BeanZ" />복사

ClassNotFoundException 의 근본 원인일 경우 전체 예외는 다음과 같다

 

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

 

 

 


Children of BeanCreationException

 

The org.springframework.beans.factory.BeanCurrentlyInCreationException

 

BeanCreationException 의 하위 클래스 중 하나 는 BeanCurrentlyInCreationException 이다

circular dependencies(순환종속성) 의 경우 생성자 주입 시 발생한다

 

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

Spring은 이러한 종류의 문제를 해결할 수 없다.

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

 

전체 예외

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 [com.baeldung.web.IBeanB]: : 
Error creating bean with name 'beanB' defined in file [...BeanB.class]: 
Unsatisfied dependency expressed through constructor argument with index 0 
of type [com.baeldung.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 [com.baeldung.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?

 

 

 

org.springframework.beans.factory.BeanIsAbstractException _

 

Bean Factory가 추상으로 선언된 Bean을 검색하고 인스턴스화하려고 시도할 때 발생할 수 있다.

public abstract class BeanA implements IBeanA {
   ...
}

XML 구성에서 다음과 같이 선언한다.

<bean id="beanA" abstract="true" class="com.baeldung.web.BeanA" />

 

 

 

다른 bean을 인스턴스화할 때와 같이 이름으로 Spring Context에서 BeanA를 검색 할 때

@Configuration
public class Config {
    @Autowired
    BeanFactory beanFactory;

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

 

다음 예외

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

 

 

전체 예외 스택 추적

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