전자정부 프레임워크 프로젝트를 Sample과 함께 생성하면,
고유의 프로젝트 소스 구조를 만들어준다.
근데 이 구조라는게, 그대로 따라서 만들다보면
"난 지금 전자정부 프레임워크를 쓰고있다"
"난 프레임워크를 쓰지만 커스터마이징까진 할줄모르는 초보다"
라는 느낌이 나게 만들어준다. 한마디로 아마추어 티가 팍팍 난다는 이야기.
투입된 프로젝트에서 업무분야 변경차 살짝 짬이 난 김에
프로젝트 내부구조를 바꾸기 위해 건드려야할 xml파일에 대해 기록해본다.
(물론 완벽히 바꾸진 않았다. 전자정부 프레임워크 내 구현된 클래스 등은 그대로 egovframework 사용 ^^;)
좌측은 전자정부 프레임워크 + 부트스트랩으로 개발했던 그룹웨어 주소록이고
Package Explorer를 떡하니 벌려도 되나 잠시 고민했지만..
어차피 정식 프로젝트도 아니고 뼈대 자체는 전자정부 프레임워크를 그대로 따왔기에 -_-
오른쪽은 나름대로 변화를 주려고 노력한 모습이다.
1) 소스폴더 내부에 egovframework라 명시된 부분을 가급적 제거하려 노력했으며
2) rte(RunTime Environment) 등 테스트유닛 등이 함께 포함되어야 의미있는 부분도 제거했다.
먼저 전자정부 프레임워크는 위키에 다음과 같이 환경설정 xml파일들을 명시했다.
하나하나 차근차근 수정한 부분을 따라가보자.
1. web.xml |
: <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:zero/spring/context-*.xml </param-value> </context-param> : <servlet> <servlet-name>action</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/zero/springmvc/dispatcher-servlet.xml, /WEB-INF/config/zero/springmvc/urlfilename-servlet.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> : <welcome-file-list> <welcome-file>/WEB-INF/jsp/ZeroMain.jsp</welcome-file> </welcome-file-list> : <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/common/error.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/common/error.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/common/error.jsp</location> </error-page> : |
2. classpath*:egovframework/spring/context-*.xml |
context-aspect.xml : <aop:config> - AOP 사용예정이라면 antpath를 적절히 변경할 것 - <aop:pointcut id="serviceMethod" expression="execution(* egovframework.rte.sample..impl.*Impl.*(..))" /> <aop:aspect ref="exceptionTransfer"> <aop:after-throwing throwing="exception" pointcut-ref="serviceMethod" method="transfer" /> </aop:aspect> </aop:config> : <bean id="egovHandler" class="zero.common.EgovSampleExcepHndlr" /> <bean id="otherHandler" class="zero.common.EgovSampleOthersExcepHndlr" /> : context-common.xml : <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:/zero/message/message-common</value> <value>classpath:/egovframework/rte/fdl/idgnr/messages/idgnr</value> <value>classpath:/egovframework/rte/fdl/property/messages/properties</value> </list> </property> <property name="cacheSeconds"> <value>60</value> </property> </bean> : - 패키지명을 수정해준다. context-common.xml 외 /WEB-INF/config/zero/springmvc/dispatcher-servlet.xml에도 있음! - <context:component-scan base-package="zero"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> : context-sqlMap.xml : <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:/zero/sqlmap/sql-map-config.xml"/> <property name="dataSource" ref="dataSource"/> </bean> : context-trancaction.xml : <aop:config> - 역시 트랜잭션 사용예정이라면 antpath를 적절히 변경할 것 - <aop:pointcut id="requiredTx" expression="execution(* egovframework.rte.sample..impl.*Impl.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" /> </aop:config> : context-validator.xml : <bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory"> <property name="validationConfigLocations"> <list> <value>/WEB-INF/config/zero/validator/validator-rules.xml</value> <value>/WEB-INF/config/zero/validator/validator.xml</value> </list> </property> </bean> : |
3. /WEB-INF/config/egovframework/springmvc/*.xml |
dispatcher-servlet.xml : - context-common.xml에도 동일하게 패키지명을 수정해주어야 한다 - <context:component-scan base-package="zero"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> : <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="zero.common.EgovBindingInitializer"/> </property> </bean> : <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="defaultErrorView" value="common/error"/> <property name="exceptionMappings"> <props> <prop key="org.springframework.dao.DataAccessException">common/dataAccessFailure</prop> <prop key="org.springframework.transaction.TransactionException">common/transactionFailure</prop> <prop key="egovframework.rte.fdl.cmmn.exception.EgovBizException">common/bizError</prop> <prop key="org.springframework.security.AccessDeniedException">common/accessDenied</prop> <prop key="org.springframework.security.AccessDeniedException">common/accessDenied</prop> </props> </property> </bean> : <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/> : <bean id="imageRenderer" class="zero.common.EgovImgPaginationRenderer"/> : context-validator.xml : <bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory"> <property name="validationConfigLocations"> <list> <value>/WEB-INF/config/zero/validator/validator-rules.xml</value> <value>/WEB-INF/config/zero/validator/validator.xml</value> </list> </property> </bean> : |
여기에 더해, iBatis를 위한 xml파일들도 다음 사항들을 수정해준다.
① sql-map-config.xml 내 sqlMap들의 경로
② sqlMap 내 VO/DTO POJO들의 경로
결국, 중요한 것은 물리적인 내부구조를 변경했을 때 이를 참조하는 설정파일들의 참조경로를 적절히 수정해주는게 주된 작업.
다른것보다 <context:component-scan>의 basc-package 항목이 두 개의 xml파일에 분리되어 있어
하나만 수정해놓고 NoSuchBeanDefinitionException을 보며 헤맬 가능성이 높다. 내가..그랬다.-_-
분리되어있는 <context:component-scan> -_-
이와 같은 구조에 대한 전자정부 프레임워크 공식포럼의 답변은 다음과 같다.
비즈니스 레이어와 클라이언트 레이어를 분리하기 위해서라..
이 답변을 이해하고 응용하려면 적어도 다중 Servlet 구조를 이해해야할 것 같은데;
역시 Spring을 제대로 이해하려면 토비의 스프링을 정독하는 수 밖에 없나보다 Ora
오늘의 삽질 종료!