이전 글에서 살펴보았듯이, 빈 구성정보를 분리하여 관리해 보겠습니다.
우선 사용자 구성정보
Bean들은 ComponentScan
을 통해 등록이 되고 있습니다.
하지만, 자동 구성정보
까지 ComponentScan
이 Bean으로 등록하고 있습니다.
이제 자동구성정보
를 ComponentScan
이 아닌 애플리케이션 실행 시 자동으로 등록
이 되게 설정하겠습니다.
우선 ComponentScan의 적용범위를 알아야 합니다.
적용 범위는ComponentScan의 패키지부터 아래의 모든 정보
를 스캔합니다.
따라서,Config
를ComponentScan
의 패키지 밖으로 빼내야 합니다.
Config 폴더를 만들어 클래스를 분리하였습니다.
이제 ComponentScan
의 관리대상 밖입니다.
애플리케이션을 실행해 보겠습니다.
ServletWebServerFactory bean defined in the context.
서블릿팩토리를 찾을 수 없다고 에러가 발생합니다.
Bean으로 등록되지 못해서 그렇습니다.
그럼 이제 Config클래스에있는 Bean들을 ComponentScan
이 아닌 자동으로 Bean으로 등록되게 해보겠습니다.
@import
를통해 Bean으로 애플리케이션 실행 시 주입할 수 있습니다.
Component와 관련된 애노테이션이 있는 클래스에@import
를 사용하면 Bean 구성정보를 직접 추가할 수 있습니다.
@Retention(RetentionPolicy.RUNTIME) // 런타임까지 애노테이션 정보가 유지되게 합니다.
@Target(ElementType.TYPE) // 클래스, 인터페이스, Enum에 부여합니다.
@Configuration
@ComponentScan
@Import({DispatcherServlet.class, TomcatWebServerConfig.class})
public @interface MySpringBootApplication {
}
@Configuration
public class DispatcherServletConfig {
@Bean
public DispatcherServlet dispatcherServlet(){
// DispatcherServlet이 이용할 컨트롤러를 찾아야 하기때문에 ApplicationContext를 생성자로 주어야합니다.
// 스프링이 알아서 ApplicationContext를 주입해 줍니다!!
return new DispatcherServlet();
}
}
@Configuration
public class TomcatWebServerConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
}
이렇게 한다면 자동구성정보를 추가할때마다 MySpringBootApplication
에 @import
에 찾아가 클래스 구정정보를 넣어주어야 합니다.
최상위 레벨에 정보가 계속 추가되는것을 좋지 않습니다.
문제 해결을 위해 EnableMyAutoConfiguration
메타 어노테이션을 생성하겠습니다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({DispatcherServletConfig.class, TomcatWebServerConfig.class})
public @interface EnableMyAutoConfiguration {
}
Enable은 ~기능을 사용하게 해줘 라는 뜻입니다.
그리고 이제 Main어노테이션인 MySpringBootApplication
메타 어노테이션에는 EnableMyAutoConfiguration
메타 어노테이션을 추가하면 됩니다.
@Retention(RetentionPolicy.RUNTIME) // 런타임까지 애노테이션 정보가 유지되게 합니다.
@Target(ElementType.TYPE) // 클래스, 인터페이스, Enum에 부여합니다.
@Configuration
@ComponentScan
@EnableMyAutoConfiguration
public @interface MySpringBootApplication {
}
이제 MySpringBootApplication
을 Config 폴더로 옮겨줄 것입니다.
그 이유는 비지니스 로직과 Config 정보를 폴더 단위로 관리하여 가독성과 유지보수에 쉽게하기 위해서 입니다.
처음 리펙토링을 했을때의 구성정보입니다.
@import
를 통해 자동구성정보
들을 MySpringBootApplication
에 구성정보를 주입하였습니다.
한단계 더 리펙토링을 진행했을떄의 구성정보입니다.
한단계 더 추상화 되었습니다.
위에 설명하였듯이, 최상위 어노테이션인 MySpringBootApplication
에 변경이 자주 일어나면 안되기 때문에,
EnableMyAutoConfiguration
어노테이션을 생성하여 자동구성정보
들을 관리하게 하였고
MySpringBootApplication
에서는 EnableMyAutoConfiguration
애노테이션을 사용하였습니다.
따라서 MySpringBootApplication
는 자동구성정보
에대해 직접적으로 알지 못하고, EnableMyAutoConfiguration
만을 바라보기때문에 느슨한 연결
이 되었습니다!
느슨한 연결
이 되었다면 유연성과 코드의 재사용성
에 용의하기때문에 유리합니다!