2013년 4월 8일 월요일

[Spring] AOP(Aspect Oriented Programming)

로직 중에는 핵심적으로 수행되는 로직과 공통으로 수행되는 로직이 존재한다. 특히 공통적으로 사용되는 기능은 로깅, 트랜잭션, 보안 등이 존재한다.

공통적으로 수행되는 로직은 아무리 단순할지라도 많은 곳에서 사용되어지면 그만큼 중복된 코드가 많아지게되고 관계가 복잡해 진다. 이러한 현상을 극복하기 위해 AOP가 등장하였다.

AOP를 가장 잘 설명해 주는 그림이다. CourseService, StudentService 그리고 MiscService가 핵심 관심 사항이고 항상 보안, 트랜잭션 등의 공통 관심 사항에 필요한 로직을 셋 다 수행하도록 되어있다.
만약 핵심 관심 사항이 늘어나거나 공통 관심 사항이 늘어날 경우에 굉장히 불필요하고 번거로운 작업이 많이 생기게 된다. 예를 들어 각각의 핵심 관심 사항에 일일이 공통 관심 사항을 설정한다는 것은 엄청난 시간과 에너지 소비일 것이다.

그러나 AOP에서는 핵심 로직을 구현한 클래스를 실행하기 전, 후에 공통 로직을 여러클래스에 미리 적용시켜 놓음으로써 번거로운 작업을 줄일 수 있다.

우선 공통 관심 사항을 구현해보자.
예)

public class LoggingAspect {
private Log log = LogFactory.getLog(getClass());

public Object logging(ProceedingJoinPoint jointPoint) throws Throwable{
log.info("기록시작");//proceed 이전에 실행
StopWatch stopWatch = new StopWatch();
try{
stopWatch.start();
Object obj = jointPoint.proceed();//실제 비지니스 메서드 호출 시점
return obj;
}catch(Throwable e){
throw e;
}finally{
stopWatch.stop();//proceed 이후에 실행
log.info("기록 종료");
log.info(jointPoint.getSignature().getName() + "메서드 실행 시간 : " + stopWatch.getTotalTimeMillis());

}
}
}
위와 같은 코드로 원하는 모든 핵심 로직에 기록을 시작하고 종료할 수 있다. jointPoint.proceed()는 핵심 로직이 수행되는 시점이다.

위에 구현한 클래스를 적용시키기 위해 XML파일 설정이 필요하다.

예) AOP설정 파일(XML)----------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<bean id="logAspect" class="kosta.LoggingAspect"></bean>

<aop:config>
<aop:pointcut expression="execution(public * kosta..*ServiceImple.*(..))"
id="servicePointcut" />
<aop:aspect id="loggingAspect" ref="logAspect">
<aop:around method="logging" pointcut-ref="servicePointcut" />
</aop:aspect>
</aop:config>

</beans>
이미 구현한 로깅 공통 관심 사항 객체를 설정한다.
aop태그를 통해 로깅의 대상이 될 메소드의 범주를 설정하고 로깅 객체를 참조한다. 그리고 대상 메소드가 호출될 때 로깅 메소드가 호출될 시점을 설정한다.

코드만으로 이해하기 어려울 수 있으니 AOP용어에 대해 살펴보자.
Aspect : 공통 관심 사항(예 : 트랜잭션, 로깅, 보안 등)
JoinPoint : Aspect가 적용 될 수 있는 지점(예: 메소드, 필드)
Poincut : 공통 관심 사항이 적용될 JoinPoint
Advice : 어느 시점에 어떤 공통 관심 기능을 적용할지 정의
Weaving : 어떤 Advice를 어떤 Pointcut에 적용시킬 것인지에 대한 설정



댓글 없음:

댓글 쓰기