본문 바로가기

IT/eGovFramework

[3] Source 내부구조 변경하기


전자정부 프레임워크 프로젝트를 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




오늘의 삽질 종료!