인수받은 시스템의 소스코드를 열어봤는데 패키지 구조가 마음에 안들었다.
패키지 구조랑 클래스 위치를 변경하고 스프링부트를 실행했는데 Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource 라면서 아래와 같은 오류가 발생했다.
2019-12-04 11:51:10.343 WARN 9333 --- [main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'siteMsgService': Unsatisfied dependency expressed through field 'siteMsgRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.navercorp.nguide.app.view.admin.siteMsg.repository.SiteMsgRepository]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2019-12-04 11:51:10.367 WARN 9333 --- [main]o.s.boot.SpringApplication : Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' is defined) Disconnected from the target VM, address: '127.0.0.1:53779', transport: 'socket'
2019-12-04 11:51:10.446 ERROR 9333 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Field siteMsgRepository in com.navercorp.nguide.app.view.admin.siteMsg.service.SiteMsgService required a bean of type 'com.navercorp.nguide.app.view.admin.siteMsg.repository.SiteMsgRepository' that could not be found. Action: Consider defining a bean of type 'com.navercorp.nguide.app.view.admin.siteMsg.repository.SiteMsgRepository' in your configuration.
에러메세지 중에서 붉은색으로 굵게 표시한 부분처럼 SiteMsgRepository라는 클래스가 있고 다른 클래스에서 @Autowired로 siteMsgRepository 필드가 선언 되어있지만 생성된 빈이 없기 때문에 오류가 발생했다.
내가 패키지 구조를 변경하면서 Spring Configuration의 패키지 경로 설정을 변경하지 않았다.
Bean 생성을 위해 스캐닝하는 패키지 경로를 정의해주어야 한다.
MyBatis 사용하는 경우
- @MapperScan(basePackages = /* 패키지 경로*/ ) 애노테이션을 정의한다.
// mybatis package 경로 변경
@MapperScan(basePackages = {
"com.navercorp.security.app.view.admin",
"com.navercorp.security.app.im",
}
public class SecurityDBConfigs {
// ...
}
JPA 사용하는 경우
- @EnableJpaRepositories(basePackages = /* 패키지 경로*/ ) 애노테이션을 정의한다.
- LocalContainerEntityManagerFactoryBean 객체의 packagesToScan 데이터(패키지경로)를 변경한다.
// jpa package 경로 변경
@EnableJpaRepositories(
basePackages = "com.navercorp.security.app.view.admin",
entityManagerFactoryRef = "securityEntityManager",
transactionManagerRef = "securityTransactionManager")
public class SecurityDBConfigs {
// ...
@Bean
public AbstractEntityManagerFactoryBean nguideEntityManager() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
// 패키지 경로 변경
factory.setPackagesToScan("com.navercorp.security.app.admin.");
return factory;
}
}
// 한 눈에 보기
@Configuration
@EnableTransactionManagement
// mybatis package 경로 변경
@MapperScan(basePackages = {
"com.navercorp.security.app.view.admin",
"com.navercorp.security.app.im",
},
annotationClass = Repository.class,
sqlSessionFactoryRef = "securityDBSqlSessionFactory")
// jpa package 경로 변경
@EnableJpaRepositories(
basePackages = "com.navercorp.security.app.view.admin",
entityManagerFactoryRef = "securityEntityManager",
transactionManagerRef = "securityTransactionManager")
public class SecurityDBConfigs {
// ...
@Bean
public AbstractEntityManagerFactoryBean nguideEntityManager() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
// 패키지 경로 변경
factory.setPackagesToScan("com.navercorp.security.app.admin.");
return factory;
}
}