Spring은 기본적으로 @SpringBootApplication 어노테이션이 붙은 Main클래스가 속한 패키지 및 하위 패키지를 스캔에서 Bean으로 등록을 한다.
그래서 ApplicationContext 인터페이스를 사용하여 getBean() 메소드를 통해 해당 Bean을 가져와서 사용할 수 있는데, 나 같은 경우는 이 getBean()에서 계속 에러가 난 경우이다.
Object bean = applicationContext.getBean("CheckLicenseEndDateScheduler");
이렇게 클래스 명을 통해서 getBean()을 하게 되면 아래와 같은 NoSuchBeanDefinitionException: No bean named 'CheckLicenseEndDateScheduler' available 이러한 에러가 나오게 되었는데,
ERROR 23-08-21 15:57:53[http-nio-8085-exec-7] [[dispatcherServlet]:175] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'CheckLicenseEndDateScheduler' available] with root cause
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'CheckLicenseEndDateScheduler' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:874)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1358)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:309)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1156)
하지만 실제로 해당 클래스는 아래와 같이 @Component 어노테이션까지 잘 정의되어있었고 패키지 경로도 맞게 들어가 있었다.
@Component
@RequiredArgsConstructor
public class CheckLicenseEndDateScheduler extends AbstractTask{
public void run() {
.
.
.
}
몇 시간의 삽질과 구글링의 끝에 chatGPT의 대답은…

수정 후 다시 디버깅해서 bean이 정상적으로 가져와졌는지 확인해 본 결과

성공했다…
그 밖에도 getBean()메소드를 통해서 bean을 가져오는 방법은 여러가지가 있는데,
// 클래스 명 전달
Test test = applicationContext.getBean(Test.class);
// 클래스 명의 첫글자 소문자로 치환후 String으로 전달
Test test = applicationContext.getBean("test");
위와 같이 Test.class에 @Component 어노테이션만 잘 정의되어있다면 따로 설정파일을 만들 필요 없이 바로 호출해서 사용하면 되고,
따로 @Bean 으로 정의해서 정의한 이름으로 호출해서 사용도 가능하다.
@Configuration
public class BeanConfig {
@Bean("beanTest")
public Test test() {
return new Test();
}
}
// 정의해놓은 bean의 이름으로 전달
Test test = applicationContext.getBean("beanTest");