Exception Handling 서비스

개요

전자정부 표준프레임워크 기반의 시스템 개발시 Exception 처리, 정확히는 Exception 별 특정 로직(후처리 로직이라고 부르기도 함)을 흐를 수 있도록 하여 Exception 에 따른 적절한 대응이 가능도록 하고자 하는데 목적이 있다.
AOP 의 도움을 받아 비즈니스 POJO와 분리되어 After throwing advice 로 정의하였다.
AOP 관련한 내용은 AOP 모듈을 참조하길 바란다.

Exception 에 대해 이야기 하겠다.
Exception 이 발생시 Exception 발생 클래스 정보와 Exception 종류가 중요하다.
Exception 발생 클래스 정보와 Exception 종류는 모두 후처리 로직의 대상일지 아닐지를 결정하는데 사용된다.

	public CategoryVO selectCategory(CategoryVO vo) throws Exception {
		CategoryVO resultVO = categoryDAO.selectCategory(vo);
		try {
    ....
 
    // 넘어온 resultVO 가 null 인경우 EgovBizException 발생 (result.nodata.msg 는 메세지 키에 해당됨)
		if (resultVO == null)
			throw processException("result.nodata.msg"); 
                        // 또는 throw processException("result.nodata.msg", 발생한 Excpetion );
		return resultVO;
	}

설명

우리는 앞에서 언급했던 Exception 후처리 방식과 Exception 이 아니지만 후처리 로직(leavaTrace)을 실행할 하는 방식에 대해 설명하도록 하겠다.
간략하게 보면
Exception 후처리 방식은 AOP(pointCut ⇒ after-throw) ⇒ ExceptionTransfer.transfer() ⇒ ExceptionHandlerService ⇒ Handler 순으로 실행된다.

LeavaTrace 는 AOP를 이용하는 구조는 아니고 Exception 을 발생하지도 않는다. 단지 후처리 로직을 실행하도록 하고자 함에 목적이 있다.
실행 순서는 LeavaTrace ⇒ TraceHandlerService ⇒ Handler 순으로 실행한다.

먼저 Exception Handling 에 대해 알아보도록 하자.

Aop Config, ExceptionTransfer 설정 및 설명


Bean 설정

Exception 후처리와 leaveaTrace 설정을 위해서 샘플에서는 두개의 xml 파일을 이용한다. (context-aspect.xml, context-common.xml)

먼저 Exception 후처리를 위한 부분을 보겠다.
Exception Handling 을 위한 AOP 설정은 아래와 같다.
비즈니스 개발시 패키지 구조는 바뀌기 때문에 Pointcut은 egov.sample.service.*Impl.*(..)) 을 수정하여 적용할 수 있다.
ExceptionTransfer 의 property 로 존재하는 exceptionHandlerService 는 다수의 HandleManager 를 등록 가능하도록 되어 있다.
여기서는 defaultExceptionHandleManager을 등록한 것을 볼 수 있다.

context-aspect.xml

...
	<aop:config>
		<aop:pointcut id="serviceMethod"
			expression="execution(* egov.sample.service.*Impl.*(..))" />
 
		<aop:aspect ref="exceptionTransfer">
			<aop:after-throwing throwing="exception"
				pointcut-ref="serviceMethod" method="transfer" />
		</aop:aspect>
	</aop:config>
 
	<bean id="exceptionTransfer" class="egovframework.rte.fdl.cmmn.aspect.ExceptionTransfer">
		<property name="exceptionHandlerService">
			<list>
				<ref bean="defaultExceptionHandleManager" />
			</list>
		</property>
	</bean>
 
	<bean id="defaultExceptionHandleManager"
		class="egovframework.rte.fdl.cmmn.exception.manager.DefaultExceptionHandleManager">
		<property name="patterns">
			<list>
				<value>**service.*Impl</value>
			</list>
		</property>
		<property name="handlers">
			<list>
				<ref bean="egovHandler" />
			</list>
		</property>
	</bean>
 
	<bean id="egovHandler"
		class="egovframework.rte.fdl.cmmn.exception.handler.EgovServiceExceptionHandler" />
...

defaultExceptionHandleManager는 setPatters() , setHandlers() 메소드를 가지고 있어 상단과 같이
등록된 pattern 정보를 이용하여 Exception 발생 클래스와의 비교하여 ture 인 경우 handlers 에 등록된 handler를 실행한다.
패턴 검사시 사용되는 pathMatcher 는 AntPathMatcher 를 이용하고 있다.

특정 pattern 그룹군을 만든후 patterns 에 등록하고 그에 해당하는 후처리 로직을 정의하여 등록할 수 있는 구조이다.

Handler 구현체

먼저 클래스에 대한 이해가 필요하다. 앞단에서 간단하게 설명을 했지만 다시 정리 하자면
Exception 발생시 AOP pointcut “After-throwing” 걸려 ExceptionTransfer 클래스의 transfer 가 실행된다.
transfer 메소드는 ExceptionHandlerManager 의 run 메소드를 실행한다. 아래는 구현예로 DefaultExceptionHandleManager 코드이다.
(구현시 필수사항) 상위클래스는 AbsExceptionHandleManager 이고 인터페이스는 ExceptionHandlerService 이다.
구현되는 메소드는 run(Exception exception) 인 것을 확인할 수 있다.

DefaultExceptionHandleManager.java

public class DefaultExceptionHandleManager extends AbsExceptionHandleManager implements ExceptionHandlerService {
 
	@Override
	public boolean run(Exception exception) throws Exception {
 
		log.debug(" DefaultExceptionHandleManager.run() ");
 
		// 매칭조건이 false 인 경우
		if (!enableMatcher())
			return false;
 
		for (String pattern : patterns) {
			log.debug("pattern = " + pattern + ", thisPackageName = " + thisPackageName);
			log.debug("pm.match(pattern, thisPackageName) =" + pm.match(pattern, thisPackageName));
			if (pm.match(pattern, thisPackageName)) {
				for (ExceptionHandler eh : handlers) {
					eh.occur(exception, getPackageName());
				}
				break;
			}
		}
 
		return true;
	}
 
}

Customizable Handler 등록

시나리오 : CustomizableHandler 클래스를 만들어 보고 sample 패키지에 있는 Helloworld 클래스 Exception 시에 CustomizableHandler 를 실행한다.

먼저 CustomHandler 클래스를 아래와 같이 만든다.
ExceptionHandleManager 에서는 occur 메소드를 실행한다.
Handler 구현체는 반드시 (필수사항) ExceptionHandler Interface를 갖는다.

CustomizableHandler.java

public class CustomizableHandler implements ExceptionHandler {
 
	protected Log log = LogFactory.getLog(this.getClass());
 
	public void occur(Exception ex, String packageName) {
 
		log.debug(" CustomHandler run...............");
		try {
			log.debug(" CustomHandler 실행 ...  ");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

CustomizableHandler 의 등록을 해보도록 하겠다.
역시서 주의해야 하는 부분은 patterns 에 sample 패키지에 있는 Helloworld 클래스 를 지정해주어야 한다.

	<bean id="exceptionTransfer" class="egovframework.rte.fdl.cmmn.aspect.ExceptionTransfer">
		<property name="exceptionHandlerService">
			<list>
				<ref bean="customizableExceptionHandleManager" />
			</list>
		</property>
	</bean>
 
	<bean id="customizableExceptionHandleManager"
		class="egovframework.rte.fdl.cmmn.exception.manager.DefaultExceptionHandleManager">
		<property name="patterns">
			<list>
				<value>**sample.Helloworld</value>
			</list>
		</property>
		<property name="handlers">
			<list>
				<ref bean="customizableHandler1" />
				<ref bean="customizableHandler2" />
				<ref bean="customizableHandler3" />
			</list>
		</property>
	</bean>
 
	<bean id="customizableHandler1" class="sample.CustomizableHandler" />
	<bean id="customizableHandler2" class="sample.CustomizableHandler" />
	<bean id="customizableHandler3" class="sample.CustomizableHandler" />

이런식으로 여러개의 Handler를 등록해줄 수 있다.

leaveaTrace 설정 및 설명


Exception 이거나 Exception 이 아닌 경우에 Trace 후처리 로직을 실행 시키고자 할 때 사용한다.
설정하는 기본적인 구조는 Exception 후처리 하는 방식과 같다. 설정파일이 context-common.xml 이다.
DefaultTraceHandleManager 에 TraceHandler를 등록하는 형태로 설정된다.

Bean 설정

...
	<bean id="leaveaTrace" class="egovframework.rte.fdl.cmmn.trace.LeaveaTrace">
		<property name="traceHandlerServices">
			<list>
				<ref bean="traceHandlerService" />
			</list>
		</property>
	</bean>
 
	<bean id="traceHandlerService" 	class="egovframework.rte.fdl.cmmn.trace.manager.DefaultTraceHandleManager">
		<property name="patterns">
			<list>
				<value>*</value>
			</list>
		</property>
		<property name="handlers">
			<list>
				<ref bean="defaultTraceHandler" />
			</list>
		</property>
	</bean>
 
	<bean id="antPathMater" class="org.springframework.util.AntPathMatcher" />
 
	<bean id="defaultTraceHandler"
		class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" />
...

TraceHandler 확장 개발 Sample

Interface TraceHandler를 아래와 같이 implements 한다.

package egovframework.rte.fdl.cmmn.trace.handler;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
 
public class DefaultTraceHandler implements TraceHandler {
 
 
    public void todo(Class clazz, String message) {
	//수행하고자 하는 처리로직을 넣는 부분...
	System.out.println(" log ==> DefaultTraceHandler run...............");
    }
 
}

leaveaTrace 코드상 발생 Sample

사용방법을 다시 상기 해보면 아래와 같다.
메세지키(message.trace.msg) 를 이용하여 메세지 정보를 넘겨 Handler 를 실행한다.

	public CategoryVO selectCategory(CategoryVO vo) throws Exception {
		CategoryVO resultVO = categoryDAO.selectCategory(vo);
		try {
		  //강제로 발생한 ArithmeticException  
			int i = 1 / 0;
		} catch (ArithmeticException athex) {
		  //Exception 을 발생하지 않고 후처리 로직 실행.
			leaveaTrace("message.trace.msg");
		}
 
		return resultVO;
	}

참고자료

 
egovframework/rte2/bsl/exception_handling.txt · 마지막 수정: 2015/04/14 11:24 (외부 편집기)
 
이 위키의 내용은 다음의 라이센스에 따릅니다 :CC Attribution-Noncommercial-Share Alike 3.0 Unported
전자정부 표준프레임워크 라이센스(바로가기)

전자정부 표준프레임워크 활용의 안정성 보장을 위해 위험성을 지속적으로 모니터링하고 있으나, 오픈소스의 특성상 문제가 발생할 수 있습니다.
전자정부 표준프레임워크는 Apache 2.0 라이선스를 따르고 있는 오픈소스 프로그램입니다. Apache 2.0 라이선스에 따라 표준프레임워크를 활용하여 발생된 업무중단, 컴퓨터 고장 또는 오동작으로 인한 손해 등에 대해서 책임이 없습니다.
Recent changes RSS feed CC Attribution-Noncommercial-Share Alike 3.0 Unported Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki