아래와 같이 동일 타입의 Bean객체를 바꾸려할 때는 어떻게 해야할까?
xml타입과 csv파일을 사용해서 읽어야 한다면 두 가지 배포버전을 만들어서 관리해야한다.
@Service
public class DoIt {
private final MakeIt makeIt;
public DoIt(@Qualifier("jaxbMakeIt") MakeIt makeit){
//....something....
}
//public DoIt(@Qualifier("csvbMakeIt") MakeIt makeit){
//....something....
//}
만약 세 번째 파일타입을 추가해야 한다면 세 가지 배포버전을 만들어서 관리해야하는 번거로움이 있다.
하지만 우리는 확장성과 유연성을 위해 spring 프레임워크를 사용하는데, 환경에 따라 빈 구성을 자동으로 도와주는 기능은 없을까?
이를 도와주는 기능이 Bean Definition Profiles이다.
Bean Definition Profiles는 의존관계를 주입할 MakeIt객체를 유연하게 선택할 수 있게 해준다.
주로 사용하는 환경을 레퍼런스에는 다음과 같이 표현하고 있다.
Bean Definition Profiles 레퍼런스
요약하면 개발서버, 배포서버 등 환경이 다를 때, 고객별로 커스터마이즈된 애플리케이션을 제공할 때 사용하는 것을 추천한다.
//Create new classfile
public class MakeProfile{
public static final String CSV_MODE = "csv_mode";
public static final String XML_MODE = "xml_mode";
private MakeProfile(){}
}
//CsvMakeIt class file
//MakeIt인터페이스의 구현체인 CsvMakeIt과 JaxbMakeIt에 어노테이션 추가
@Profile(MakeProfile.CSV_MODE)
@Repository //ComponentScan을 통해 자동으로 Bean을 찾아 등록하기 위한 어노테이션
public class CsvMakeIt implements MakeIt{
//...something..
}
//JaxvMakeIt class file
@Profile(MakeProfile.XML_MODE)
@Repository
public class JaxbMakeIt implements MakeIt{
//...something..
}
profile설정을 위한 새로운 MakeProfile 클래스파일을 만들어 각 모드이름을 정의한다.
이후 기존 구현클래스에 @Profile 어노테이션을 작성하고 모드를 명시하면 된다.
그리고 MakeIt을 사용하는 DoIt클래스의 @Qualifier을 삭제한다.
@Service
public class DoIt {
private final MakeIt makeIt;
public DoIt(MakeIt makeit){
//....something....
}
이렇게까지만 한다면 설정은 끝났지만 csv와 xml중에서 무엇을 활성화 할 것인지를 정하지 않았다.
그래서 마지막으로 사용하려는 main클래스, test클래스 앞에 @ActiveProfiles를 통해 profiles를 활성화 시키면 끝이다.
@ActiveProfiles(MakeItProfile.CSV_MODE)
public class DoItTest{
//..something..
}
우리는 ComponentScan을 사용하여 자동으로 Bean객체를 찾아 의존관계를 주입한다.
하지만 ComponentScan은 기본적으로 타입을 기준으로 의존관계를 주입하는데, CsvMakeIt과 JaxbMakeIt처럼 같은 MakeIt타입 구현체가 두개 이상인 경우 @Qualifier와 같이 직접 명시해줘야 하는 불편함이 있었다.
우리는 이를 Bean Definition Profiles를 통해 유연하게 해결할 수 있음을 확인해보았다.