https://www.baeldung.com/spring-nosuchbeandefinitionexception
+ 예외처리 리스트
https://www.baeldung.com/spring-exceptions
Spring org.springframework.beans.factory.NoSuchBeanDefinitionException.
Spring Context에 정의되지 않은 bean을 해결하려고 시도할 때 BeanFactory 에 의해 발생하는 일반적인 예외들이다
Cause: No Qualifying Bean of Type […] Found for Dependency
단순히 정의되지 않은 빈을 주입하려고 시도하는 경우
예시코드
@Component
public class BeanA {
@Autowired
private BeanB dependency;
//...
}
종속성 BeanB가 Spring 컨텍스트에 정의되지 않은 경우 부트스트랩 프로세스는 no such bean 정의 예외 와 함께 실패한다 .
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.baeldung.packageB.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)}
이 종속성에 대한 autowire 후보로 자격이 있는 최소 1개의 bean이 있을 것이다 .
컨텍스트에 BeanB가 존재하지 않을 수 있는 한 가지 이유는 — 빈이 클래스 경로 스캐닝 에 의해 자동으로 선택되고 BeanB 가 빈( @Component , @Repository , @Service , @Controller 등) 으로 올바르게 주석이 달린 경우 — 다음과 같을 수 있기 때문에. Spring이 검사하지 않는 패키지 에 정의되어야한다.
package com.baeldung.packageB;
@Component
public class BeanB { ...}
클래스 경로 스캐닝은 다음과 같이 구성될 수 있다
@Configuration
@ComponentScan("com.baeldung.packageA")
public class ContextWithJavaConfig {
...
}
Bean이 자동으로 스캔되지 않고 대신 수동으로 정의되면 BeanB 는 단순히 현재 Spring Context에 정의되지 않는다.
https://delightpip.tistory.com/196
Cause: Field […] in […] Required a Bean of Type […] That Could Not Be Found
BeanB가 BeanA 에 연결되어 있지만 정의되지 않은 경우(위와 동일)
@Component
public class BeanA {
@Autowired
private BeanB dependency;
//...
}
BeanA 로드를 시도
@SpringBootApplication
public class NoSuchBeanDefinitionDemoApp {
public static void main(String[] args) {
SpringApplication.run(NoSuchBeanDefinitionDemoApp.class, args);
}
}
해당 에러 메세지
***************************
APPLICATION FAILED TO START
***************************
Description:
Field dependency in com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanA required a bean of type 'com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB' that could not be found.
Action:
Consider defining a bean of type 'com.baeldung.springbootmvc.nosuchbeandefinitionexception.BeanB' in your configuration.복사
여기서 com.baeldung.springbootmvc.nosuchbeanddefinitionexception 은 BeanA , BeanB 및 NoSuchBeanDefinitionDemoApp 용 패키지이다
Cause: No Qualifying Bean of Type […] Is Defined
컨텍스트에 하나가 아닌 두 개의 Bean 정의가 존재하는 경우
인터페이스 IBeanB가 BeanB1 과 BeanB2 라는 두 개의 빈으로 구현한 코드
@Component
public class BeanB1 implements IBeanB {
//
}
@Component
public class BeanB2 implements IBeanB {
//
}
BeanA가 이 인터페이스를 autowires하는데 Spring은 주입할 두 구현 중 어느 것을 알 수 없다.
@Component
public class BeanA {
@Autowired
private IBeanB dependency;
...
}
Spring 3.2.1 이전
BeanFactory 에 의해 발생되는 NoSuchBeanDefinitionException을 발생시킨다
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type
[com.baeldung.packageB.IBeanB] is defined:
expected single matching bean but found 2: beanB1,beanB2
Spring 3.2.1 이후로 다른 예외처리가 됨
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.baeldung.packageB.IBeanB] is defined:
expected single matching bean but found 2: beanB1,beanB2
해결책은 연결하려는 bean의 이름을 정확히 지정하기 위해 @Qualifier 주석을 사용해준다
@Component
public class BeanA {
@Autowired
@Qualifier("beanB2")
private IBeanB dependency;
...
}
이제 Spring은 BeanB1 또는 BeanB2 ( BeanB2 의 기본 이름은 beanB2 ) 중 어떤 bean을 주입할지 결정할 수 있게 된다
Cause: No Bean Named […] Is Defined
정의 되지 않은 bean이 Spring 컨텍스트에서 이름으로 요청될 때 발생한다
@Component
public class BeanA implements InitializingBean {
@Autowired
private ApplicationContext context;
@Override
public void afterPropertiesSet() {
context.getBean("someBeanName");
}
}
someBeanName에 대한 bean 정의가 없으므로 다음 예외가 발생하게 된다.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'someBeanName' is defined
No bean named X is defined. 이렇게 나옴
Cause: Proxied Beans
프록시는 대상 bean을 확장하지 않는다다 (그러나 동일한 인터페이스를 구현합니다).
이 때문에 bean이 인터페이스에 의해 주입되면 올바르게 연결된다.
그러나 bean이 실제 클래스에 의해 주입된 경우 프록시가 실제로 확장되지 않기 때문에 Spring은 클래스와 일치하는 bean 정의를 찾지 못한다
bean이 프록시되는 매우 일반적인 이유는 Spring 트랜잭션 지원 , 즉 @Transactional 로 주석이 달린 bean이다.
예를 들어 ServiceA가 ServiceB를 주입 하고 두 서비스가 모두 트랜잭션인 경우 클래스 정의에 의한 주입은 작동하지 않는다.
@Service
@Transactional
public class ServiceA implements IServiceA{
@Autowired
private ServiceB serviceB;
...
}
@Service
@Transactional
public class ServiceB implements IServiceB{
...
}
interface 로 올바르게 주입하면 동일한 두 서비스가 작동한다.
@Service
@Transactional
public class ServiceA implements IServiceA{
@Autowired
private IServiceB serviceB;
...
}
@Service
@Transactional
public class ServiceB implements IServiceB{
...
}
'Web > spring' 카테고리의 다른 글
[Spring Exception] Hibernate Mapping Exception – Unknown Entity (0) | 2023.04.10 |
---|---|
[Spring Exception]Guide to Spring NonTransientDataAccessException (0) | 2023.04.10 |
[Spring Exception] Spring BeanDefinitionStoreException (0) | 2023.04.08 |
[Spring Exception] Spring DataIntegrityViolationException (0) | 2023.04.08 |
[Spring Exception] Spring BeanCreationException (0) | 2023.04.07 |