@ContextConfiguration을 붙여주는 과정에서 에러가 생겼다.
9월 24, 2022 11:45:31 오후 org.springframework.context.support.AbstractApplicationContext refresh
경고: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
9월 24, 2022 11:45:31 오후 org.springframework.test.context.TestContextManager prepareTestInstance
심각: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@7e057f43] to prepare test instance [org.example.guestbookupgrade.dao.GuestbookDaoTest@61a91912]
java.lang.IllegalStateException: Failed to load ApplicationContext
현재 문제점은, @ContextConfiguration의 인자로 어떤 것을 주어야 하는지 감이 잡히지 않는다는 것이다.
1. @ContextConfiguration
동일함(내부적으로 생성된 스프링 빈 컨테이너가 사용할 설정파일을 지정할 때 사용합니다.
생성된 스프링 컨테이너에 스프링 빈을 추가하기 위해서는 application-context.xml 파일과 같은 설정 파일을 읽어야 하는데, 이런 설정파일을 로드하는 어노테이션이 ContextConfiguration이다.
(*추가 : 참고로, 현재 우리는 xml파일로 빈을 등록하지 않고, "java config 클래스로 빈을 등록"하고 있다. 즉, java config 클래스로 스프링 컨테이너 설정을 지정해주고 있다. 따라서 파라미터로 xml파일을 등록하는 것이 아니라, java config 클래스를 등록하면 된다!!)
만약 스프링 컨테이너가 필요 없다면, 즉, 스프링 빈 팩토리에서 빈을 로드하는 것이 아닌, 직접 new로 객체를 생성해가며 테스트 코드를 작성할 것이라면 위의 어노테이션을 제거해도 된다.
[문제점]
위와 같은 어노테이션인데, 현재 내 프로젝트에서는 config 파일로도 설정이 있고, web.xml에도 context 설정이 있어서 뭘 넣어야 하는지 모르겠다. 둘 다 넣어보았지만, class 또는 location 하나만 지정해야 한다는 에러를 마주했다.
[시도 중인 해결책]
1. 둘 다 넣어보기 - 실패
2. 하나씩 넣어보기 - 실패
3. spring으로 test 클래스 작성하는 방법 찾아보기
[결론]
현재 우리는 java config 클래스로 스프링 컨테이너의 설정을 지정해주므로, class를 넣어주면 해결된다!!!!
2. @ComponentScan(basePackages={" "})
프로젝트 실습에서, java config 파일을 크게 2부분으로 분리하여 사용하였다.
프레젠테이션 레이어와, 비즈니스 레이어로 분리하여 config 파일을 작성하였다.
1. 프레젠테이션 레이어 : WebMvcContextConfiguration
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"org.example.guestbookupgrade.controller"})
public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
2. 비즈니스 레이어 : ApplicationConfig, DBConfig
@Configuration
@ComponentScan(basePackages = {"org.example.guestbookupgrade.service","org.example.guestbookupgrade.dao"})
@Import({DBConfig.class})
public class ApplicationConfig {
}
@Configuration
@EnableTransactionManagement
public class DBConfig implements TransactionManagementConfigurer {
이때, 각 config 파일에 @Configuration을 붙이고, @ComponentScan을 붙인다.
중요한 것이, ApplicationConfig의 @ComponentScan의 basePackages에 "WebMvcContextConfiguration이 들어가있는 패키지"가 포함되면 안된다!!
설정을 분리하고, ComponentScan도 따로 진행하기 때문에, 서로가 서로의 configuration 파일을 포함하지 않도록 해야한다!
(*추가 WebMvcContextConfiguration은 DispatcherServlet이 만들어내는 스프링 컨텍스트에 대한 설정이고,
ApplicationConfig은 ContextLoadListener가 만들어내는 스프링 컨텍스트에 대한 설정이기 때문에, 각자의 componentscan의 범위가 겹치면 안되는 것이다)
위와 같이, controller, service, dao와 같이 더 구체적인 패키지로 지정해주어 설정의 분리를 완벽하게 해주어야 한다.
[참고 블로그]