둘러보기 생략.
 

Bean 설정 문제로 인해 ApplicationContext가 동작하지 않는 문제...

안녕하세요.

프로젝트 현장에서 발생하고 있는 문제인데요..
문제라고 하기 보다는 개발단계에서 불편한 사항정도 되겠네요..

현재 Anyframe Core, 사실 Spring Framework 자체에서
ApplicationContext초기화시 Bean 설정에 문제가 있는경우,
Exception을 throws 하면서 사용할 수 없게 되는것 같습니다.

현재 여러 개발자들이 개발중에 있고 모든 소스들의 형상이 관리되는 상황에서,
한사람의 잘못된 형상반영으로 인해 많은 사람들이 테스트를 하지 못하는 상황에 놓일 수 있습니다.
물론 해당 Bean 설정을 제외하면 정상적으로 동작을 하지만..
개발자들에게 그러한 부담을 주긴 좀 미안하더군요..

혹시, ApplicationContext 초기화시 Bean오류가 발생했을때에
해당 Bean만 skip 하는 방안이 있는지요?

p.s. 물론 운영단계에서는 사용하지 않아야 겠지요..

답변입니다.

말씀하신대로, ApplicationContext 초기화 시 Spring Bean들 중 하나라도 문제가 있으면 전체 서비스가 동작하지 않습니다.

문제있는 몇몇 Bean 때문에 전체 서비스가 동작하지 않는 이 상황을 풀기 위해서는
다음과 같이 2가지 방식 중 한가지를 채택할 수 있을 것 같습니다.

1. Bean을 lazy init 시킨다.
(spring xml 파일에 다음과 같이 작성해주시면 됩니다.)
Lazy init 설정을 하게 되면, 문제있는 Bean을 직접 호출할 때 까지 인스턴화되는 것을
미루기 때문에 다른 Bean들은 사용할 수 있습니다.

이때 하나의 Bean만 Lazy init 시키거나 전체 Bean을 Lazy init 시킬 수 있는데
전체 Bean을 한번에 제어하기는 어렵고, 각 Spring XML 파일 별로 제어할 수 있습니다.

* 하나의 Bean을 Lazy init 시키는 방법
모든 bean이 아닌, 특정 bean에 대해서만 lazy init 시킬 경우 아래와 같이 작성해주시면 됩니다.

<bean id="userDAO" class="com.sds.emp.user.impl.UserDAO" lazy-init="true"> 

* XML에 정의된 전체 Bean을 Lazy init 시키는 방법
(각 XML 파일 별로 동작함에 유의해주세요)

<beans default-lazy-init="true"> 
   <!-- no beans will be eagerly pre-instantiated... --> 
</beans>

2. Spring을 확장한다.
Spring의 원 소스코드를 그대로 고치는 것은 권하지 않고, 필요 시 확장하여 사용하실 수 있을 것 같습니다.(테스트용도로)

본래 Spring에서는 ApplicationContext 생성 시 각 Bean 에 대한 인스턴스를 만들어내는데, 이때 에러가 발생하면 exception을 던져서 전체 applicationContext 생성을 막고 있습니다.

이를 변경하여 해당 Bean 생성시 에러가 나면 exception을 catch 절에서 잡아내어, 그 다음 bean을 계속해서 생성시킬 수 있게 합니다.

* Spring 소스 코드를 직접 고치지 않고 확장하여 고치기 위해서는 아래와 같이 몇몇가지의 class를 수정해주어야 합니다.
- AbstractBeanFactory 클래스의 getBean 메소드 내에서 try ~ catch 구문을 추가하여
exception을 잡아내주면 됩니다.
- Spring 소스 코드를 직접 고치지 않고 위와 같이 하기 위해서는 web.xml 설정부터
변경시켜주셔야 합니다.
web.xml에 등록하는 ContextLoaderListener 부터 확장해주셔야 합니다.
- ContextLoader의 loadParentContext(ServletContext servletContext) 메소드 확장
- SingletonBeanFactoryLocator의 useBeanFactory 메소드 확장
createDefinition 메소드 확장
. 이 createDefinition 메소드 내에서 DefaultListableBeanFactory factory =
new DefaultListableBeanFactory(); 대신 확장한 factory를 생성시켜서
getBean 메소드를 오버라이드하도록 합니다.

제가 간략하게 작성해보았는데요, 혹시 문제가 발생하시면 다시 연락해 주세요.
감사합니다.