AnnotationConfigApplicationContext를 이용하여 XML 전혀 없는 standalone TCP-IP 애플리케이션을 제작하고 있습니다. 문제는 SocketServer/Client를 띄우게 되는데 커스터마이즈된 환경설정을 읽어들여 띄워야 한다는 제약조건이 있습니다.
현재 @Configuration과 @Bean, @Service의 조합을 통하여 필요한 객체들을 생성하는 데 소켓 서버를 생성하는 순서는 명확하게 기준이 있어야 합니다.
1. Configuration file을 로드한다.
2. 로드된 파일의 내용을 읽어들여 시스템 정보를 취합한다.
3. 동적인 데이터베이스 쿼리를 읽어들여 메타정보를 등록한다.
4. TCP 채널을 오픈한다.
5. 채널 오픈 후 앞서 생성된 빈들을 활용하여 초기 연결 조정작업을 수행한다.
#4, #5는 해당하는 작업은 #1, #2, #3번이 없으면 안되는 작업입니다.
@Configuration과 @Import를 이용하면 작업이 되겠지만 유연성이 scan 메소드를 통한 package 자동 빈 등록의 장점이 사라지게 되는 단점이 발생을 하네요.
스캔을 해버리면 패키지명의 순서에 따라 검색 후 빈을 등록하므로, ASCII 코드의 뒤에 해당하는 알파벳으로 시작하는 패키지의 @Component를 앞선 알파벳 패키지에서 참조하면 100% NPE가 발생을 하게 되네요.
예를 들면 org.jboss.a 패키지에서 org.jboss.b 패키지의 빈을 구동시 인젝션 시키고 싶은 경우입니다.
빈이 생성되는 순서가 중요한 경우에는 @DependsOn을 사용하시면 되요. 제가 제대로 이해한 것인지 모르겠지만, 만약 A 빈이 반드시 먼저 만들어지고 나서 B 빈이 만들어져야(또는 초기화 작업이 일어나야) 한다면
@Component
class A { .. }
@Component
@DependsOn("a")
class B {
@Autowired A a;
...
}
라고 하시면 되죠.
그런데 B빈에서 DI(@Autowired같은)로 A를 참조한다면 이 때는 초기화 메소드(@PostConstruct가 붙은 메소드)에서 작업을 하셔야 해요. B의 생성자가 호출되는 시점에는 아직 A가 주입되지는 않은 상태기 때문에 생성자에서 A를 사용하는 작업을 하시면 안되죠.
도움이 되셨는지 모르겠네요. 더 질문이 있으시면 KSUG(groups.google.com/group/ksug)에 질문을 올려보세요.