본문 바로가기
Spring

BeanCreationException, NoSuchBeanDefinitionException 에러 해결

by Big Sun 2022. 8. 19.
728x90

this.userDAO is null - NullPointerException (tistory.com)

 

this.userDAO is null - NullPointerException

현재, login.jsp에 들어가서 로그인을 하려는 상태이다. 로그인을 시도하면 위와같은 에러가 뜬다. 도대체 왜 이러는 걸까?? 일단, 코드를 따라가보도록 하자!! web.xml에서 *.do는 모두 presentation-layor.x

rasony.tistory.com

 

위 포스팅가 내용이 이어집니다.

 

아래는 에러 내용이다. 색칠된 부분을 유심있게 읽어보자

 

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0' defined in ServletContext resource [/WEB-INF/config/presentation-layor.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'login' defined in ServletContext resource [/WEB-INF/config/presentation-layor.xml]: Cannot resolve reference to bean 'userService' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userService' available

 

 

에러의 내용을 읽어보면, presentaion-layor.xml에서 userService에 해당하는 bean이 생성되지 않았다라는 것을 알 수 있습니다.

 

	<bean id="login" class="sonny.spring.web.user.LoginController">
		<constructor-arg ref="userService"></constructor-arg>
	</bean>

userService에 해당하는 객체는 applicationContext.xml에서 생성하도록 하였는 데 이게 어찌된 일일까요?

 

 

<!-- DI -->
	<context:component-scan base-package="sonny.spring.web"></context:component-scan>
@Service("userService")
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDAO userDAO;

	@Override
	public UserVO getUser(UserVO vo) {
		return userDAO.getUser(vo);
	}
}

분명, userService 객체는 application.xml에서 생겼습니다. 하지만, presentationlayor.xml에서는 확인 되지 않습니다.

따라서, application.xml에서 만들어진 객체 presentationlayor.xml과 공유가 되지 않는 다는 것을 유추할 수 있습니다.

 

 

이를 알기 위해서는,  RootApplicationContext와 WebApplicationContext에 대하여 알아야한다.

 

먼저, RootApplicationContext는 이름에서부터 알 수 있듯이 최상위 ApllicationContext이며, WebApplicationContext의 부모 Context이며 자식에게 자신의 설정을 공유할 수 있다. 역은 불가능 하다.

 

WebApplicationContext는 Servlet의 단위인 ApplicationContext이다. RootApplicationContext의 자식 Context이며, 부모의 설정에 접근할 수 있다.

 

현재 설정을 그림으로 표현하자면, 아래와 같다.

이 문제를 필요하려면 빨간색으로 동그라미 친 화살표가 필요하다.

 

이는 바로 ContextLoaderListener 이다.

 

web.xml에 다음과 같은 코드를 추가해주면 된다.

 

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

ContextLoaderListener는 RootApplicationContext를 생성하는 클래스이다.

위 코드를 보면, applicationContext.xml을 RootApplicationContext로 지정한다는 내용이다.

따라서, applicationContext.xml이 먼저 실행되고, 그 다음에 presentationlayor.xml이 실행된다.

presentationlayor.xml은 applicationContext.xml에 있는 내용을 공유 받을 수 있기 때문에 userService를 공유할 수 있다!

 

 

이후 실행하면, 로그인이 성공적으로 되는 것을 확인할 수 있다.

 

Spring MVC 구조(2) (tistory.com)

 

Spring MVC 구조(2)

Spring MVC 구조 (tistory.com) DispatcherServlet 등록 action org.springfra.." data-og-host="rasony.tistory.com" data-og-source-url="https://rasony.tistory.com/61?category=1069312" data-og-url="https:..

rasony.tistory.com

 

 

위 포스팅에서 Spring의 구조를 다루고 있다. 참고해보면 좋을 듯 하다.

728x90