Article Category

분류 전체보기 (202)
사는 이야기 (15)
Programming (174)
Photo (5)
게임 (2)
프로젝트 (0)

Recent Comment

Recent Trackback

Calendar

«   2009/05   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

Archive

  • Total96,717
  • Today3
  • Yesterday4
  1. 2009.05.18
    AOP

Aspect Oriented Programming

다음 내용은 ZDNet Korea의 제휴 매체인 마이크로소프트웨어에 게재된 내용에서 발췌함.

관점지향 프로그래밍(Aspect Oriented Programming, 이하 AOP)은 지금까지의 프로그래밍 기술 변화의 흐름에 다른 차원의 관점을 제시함으로써 새로운 프로그래밍 패러다임을 이끌어내고 있다고 볼 수 있다. AOP의 필요성을 이해하는데 기초가 되는 개념은 Separation of Concerns로, 다음과 같이 거의 모든 프로그래밍 패러다임은 바로 이 Separation of Concerns 과정을 통해 문제 영역을 독립적인 모듈로 분해한다.
  • 절차적 프로그래밍 : 분리된 관심을 프로시저로 구성
  • 객체지향 프로그래밍(Object Oriented Programming, 이하 OOP) : 분리된 관심을 클래스로 작성

AOP 필요성

AOP는 OOP를 적용한다고 할지라도 결코 쉽게 분리된 모듈로 작성하기 힘든 요구사항이 실제 어플리케이션 설계와 개발에서 자주 발견된다는 문제 제기에서 출발한다. AOP에서는 이를 Crosscutting Concerns(횡단 관심)라고 한다. 또한 해당 시스템의 핵심 가치와 목적이 그대로 드러난 관심 영역을 Core Concerns(핵심 관심)라고 부른다. 이 Core Concerns는 기존의 객체지향 분석/설계(OOAD)를 통해 쉽게 모듈화와 추상화가 가능하지만 Crosscutting Concerns은 객체지향의 기본 원칙을 지키면서 이를 분리해서 모듈화하는 것이 매우 어렵다.
예를 들어, 은행 업무를 처리하는 시스템을 생각해보면 Core Concerns는 예금입출금, 계좌간이체, 이자계산, 대출처리 등으로 구분할 수 있다. 이는 전체 어플리케이션의 핵심 요구 사항과 기능들을 구분해서 모듈화할 수 있고 OOP에서라면 클래스와 컴포넌트 형태로 구성이 가능하다. 하지만 현실은 그렇지 못하다. 실제로 개발되어 돌아가는 각 모듈에는 해당 업무를 처리하기 위한 로직만 존재해서는 불완전할 수밖에 없다. 일단 각 업무를 처리하는 클래스와 구현된 메소드에는 향후 시스템을 분석하거나 추적을 위해 로그를 작성해야 하며, 인증받은 사용자가 접근하는지를 체크하고 권한 여부를 따지는 보안 기능이 필요하다. 또한 내부에서 사용하는 Persistence 처리를 위해 Transaction을 시작하고, 또 필요에 따라서 그것을 Commit 또는 Rollback하는 부분도 추가되어야 한다. 예외 상황이나 문제가 발생했을 때는 그것을 기록에 남기는 부분도 있어야 하고, 필요하면 관리자에게 이메일을 발송해야 한다.

이러한 부가적인 기능들은 각각 구현을 독립적인 클래스로 작성될 수 있지만, 그렇게 구현된 기능들을 호출하고 사용하는 코드들이 핵심 모듈 안의 필요한 영역에 모두 포함될 수밖에 없다. 로깅, 인증, 권한체크, DB 연동, 트랜잭션, 락킹, 에러처리 등의 기능을 아무리 뛰어난 OOP 기술을 이용해 모듈로 구성하고 추상화를 통해 최대한 독립시킨다고 해도 핵심 모듈의 모든 클래스와 메소드 속에 이와 연동되는 부분이 매우 깊이 그리고 상당한 양을 갖으면서 자리 잡게 된다.

실제로 모듈화가 잘 된 어플리케이션 클래스를 보더라도 핵심 기능을 위한 코드보다 부가적인 기능과 처리를 위한 부분의 양이 더 많아지게 되는데 만약 다른 종류의 로깅 플랫폼을 사용해 로그 처리하는 클래스와 메소드가 달라지고 로그 메시지가 변경되어야 한다면 개발자들은 모든 클래스 안에 있는 로그 관련 코드를 일일이 다 수정해 주는 수밖에 없다. 그러다가 만약 중요한 클래스에서 한두 군데 로그 기록 코드가 빠졌고 이로 인해 결과를 확인하는데 문제가 생겼다면 이를 다시 확인하고 찾아내는 일만 해도 엄청난 작업이 아닐 수 없을 것이다.
이렇게 작성된 어플리케이션은 몇 가지 심각한 문제를 가지고 있다.
  • 중복되는 코드 : 복사-붙이기에 의해 만들어진 여러 모듈에서 중복되는 코드의 문제점은 이미 잘 알려져 있다. 하지만 AOP를 사용하지 않은 대부분의 어플리케이션에서는 어떠한 추상화와 리팩토링을 통해서도 반복되는 코드를 피하기가 어렵다.
  • 지저분한 코드 : Crosscutting Concerns과 관련된 코드들이 핵심 기능 코드 사이 사이에 끼어들어가 있기 때문에 코드가 지저분해지고 이에 따라 가독성이 떨어지며 개발자들의 실수나 버그를 유발하고 후에 코드를 유지보수하는데 큰 어려움을 준다.
  • 생산성의 저하 : 어플리케이션 개발자들이 자주 등장하는 Crosscutting Concerns을 구현한 코드를 함께 작성해야 하기 때문에 개발의 집중력을 떨어뜨리고 결과적으로 전체 생산성의 저하를 가져온다. 또 모듈별로 개발자들을 구분하고 분산시키는 것에 한계가 있다.
  • 재활용성의 저하 : OOP의 장점인 재활용성이 매우 떨어진다.
  • 변화의 어려움 : 새로운 요구사항으로 인해 전체적으로 많은 부분에 영향을 미치는 경우 쉽게 새로운 요구사항을 적용하기 힘들게 된다. 또 새로운 관심 영역의 등장이나 이의 적용을 매우 어렵게 한다.

AOP 동작 원리

AOP가 Core Concerns 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 Weaving 또는 CrossCutting이라고 불리는 특수한 작업이 필요하다. Core Concerns 모듈이 자신이 필요한 Crosscutting Concerns 모듈을 찾아 사용하는 대신에 AOP에서는 Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 필요한 Crosscutting Concerns 코드가 동작하도록 엮어지게 만든다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 Crosscutting Concerns 기능을 효과적으로 적용해 낼 수 있다.

이런 작업은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니며 본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발되면서라고 볼 수 있다. 그는 Asepct라는 용어와 함께 AOP라는 표현을 처음 사용하기 시작했고, 자바 VM과 호환되는 최초의 AOP 툴인 AspectJ를 구현해 냈다.
AspectJ는 자바의 언어를 확장한 형태의 구조로 개발됐는데 자바의 클래스와 유사한 개념인 AOP의 Aspect를 작성하는 방법을 통해 AOP의 기능을 사용할 수 있도록 했다. 이렇게 만들어진 Aspect는 AspectJ의 특별한 컴파일러를 통해 자바 VM에서 사용될 수 있는 코드로 만들어진다. 바로 이때 AOP의 Weaving 작업이 일어난다. Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 Aspect 형태로 만들어진 Crosscutting Concerns 코드들이 삽입되어 Aspect가 적용된 최종 바이너리가 만들어지는 것이다. AOP를 이용하면 개발자들은 Crosscutting Concerns 모듈을 각각 독립된 모듈로 중복없이 작성하고 이를 Weaving을 통해 Core Concerns 모듈과 결합시키기 때문에 서로 독립성을 가진 다차원의 모듈을 작성할 수 있다.

대표적인 AOP 툴

AOP는 OOP의 확장에 가깝기 때문에 전용 언어나 독립된 개발 툴을 가지고 있지 않고 대신 기존의 OOP를 확장한 언어 확장(languageextension) 또는 툴이나 프레임워크 형태로 사용할 수 있게 되어 있다. 대표적으로 AOP 구현의 시초가 된 이클립스 프로젝트의 AspectJ를 들 수 있다. AspectJ는 초기에 제록스 PARC 연구소에서 개발되었다가 2002년에 이클립스 프로젝트에 기증되었고, 현재 IBM의 전폭적인 지원을 받으면서 개발되어 사용되고 있다. 그리고 BEA가 중심이 되어 개발하고 있는 AspectWerkz가 있다. AspectWerkz는 AspectJ와 달리 자바 언어 자체를 확장하지 않고 기존의 자바 언어만으로 AOP의 사용이 가능하도록 되어 있다. 그리고 의존성 삽입(Dependency Injection, 이하 DI) 기반의 프레임워크로 유명한 SpringAOP가 있다. 가장 최근에 등장한 AOP로는 JBossAOP도 있다. SpringAOP와 함께 대표적인 인터셉터체인 방식의 AOP로 꼽힌다.

  AspectJ AspectWerkz JBossAOP SpringAOP
출시 2001 2002 2004 2004
버전 1.2.1 2.0 1.3.0 1.2.5
Aspect 선언 전용 코드 XML, Annotation XML, Annotation XML
Advice 전용 코드 자바 메소드 자바 메소드 자바 메소드
JoinPoint 메소드, 생성자, Advice, Field Access, 인스턴스 메소드, 생성자, Advice, Field Access, 인스턴스 메소드, 생성자, Advice, Field Access, 인스턴스 메소드
Pointcut 매칭 Signature, WildCard, Annotation Signature, WildCard, Annotation Signature, WildCard, Annotation 정규식
Weaving 컴파일 및 로딩 타임, 바이트 코드 생성 컴파일 및 로딩 타임, 바이트 코드 생성 런타임 인터셉션 및 Proxy 런타임 인터셉션 및 Proxy
IDE 지원 Eclipse, JDeveloper, JBuilder, NetBeans Eclipse, NetBeans Eclipse  
  • AspectJ
    AspectJ의 가장 큰 특징은 다른 AOP 툴과는 달리 자바 언어를 확장해서 만들어진 구조라는 것이다. 마치 새로운 AOP 언어를 사용하듯이 aspect라는 키워드를 이용해 Aspect나 Pointcut, Advice를 만들 수 있다. 따라서 일반 자바 컴파일러로는 컴파일이 불가능하고 특별한 AOP 컴파일러를 사용해야 한다. 하지만 이렇게 만들어진 바이너리는 표준 JVM에서 동작 가능한 구조로 되어있기 때문에 특별한 클래스 로더의 지원 없이도 실행 가능하다. AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴이다. 동시에 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기 때문에 가장 이상적인 AOP 툴로 꼽히고 있다. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고 프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. Weaving이 컴파일시에 일어나기 때문에 Pointcut에 의해 선택된 모든 클래스들은 Aspect가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.

  • AspectWerkz
    AspectWerkz는 AspectJ와는 달리 자바 언어를 확장하지 않는다. 따라서 표준 자바 클래스를 이용해서 AOP를 구현해 낼 수 있다. 일반 클래스와 메소드를 이용해 쉽게 구현이 가능한 Advice와 달리 복잡한 문법이 필요한 Pointcut은 별도의 XML 파일을 이용해 설정할 수 있도록 되어 있다. 자바 클래스와 XML 설정 파일의 접근법에 익숙한 개발자들에게는 매우 편리한 접근 방식이라고 볼 수 있다. 최근에는 JDK5의 지원에 따라 Annotation을 이용할 수 있어 더욱 편리해졌다. Weaving은 특별한 클래스 로더를 이용한 로딩타임 바이트코드 생성을 이용한다. AspectJ 못지않은 다양한 JoinPoint와 AOP기능을 지원하고 있으며 편리한 개발을 위한 IDE 플러그인이 개발되어 있다.

  • JBossAOP
    JBossAOP는 기본적으로 컨테이너에서 동작하지만 컨테이너와 상관없는 독립된 자바 프로그램에서도 사용할 수 있다. 하지만 주 용도는 JBoss 서버와 앞으로 나올 EJB3 컨테이너 등에 AOP를 적용하는 데에 사용되어지는 것이다. AspectWerkz와 마찬가지로 Advice는 표준 자바 코드로 작성하고 Pointcut과 다른 설정은 XML 파일이나 JDK5의 Annotation으로 작성할 수 있다. 아직까지는 JBoss 사용자의 일부에서만 사용되고 있으나 향후 EJB3를 중심으로 한 POJO 기반의 엔터프라이즈 미들웨어 프레임워크가 개발되어짐에 따라 점차로 사용률이 올라갈 것으로 기대된다.

  • SpringAOP
    SpringAOP는 Spring Framework의 핵심기능 중의 한가지로 Spring의 Dependency Injection(이후 DI) 컨네이너에서 동작하는 엔터프라이즈 서비스에서 주로 사용된다. SpringAOP는 다른 AOP와 달리 기존 클래스의 바이트코드를 수정하지 않는다. 대신 JDK의 Dynamic Proxy를 사용해서 Proxy 방식으로 AOP의 기능을 수행한다. 이 때문에 다른 AOP의 기능과 비교해서 매우 제한적인 부분만을 지원한다. 하지만 SpringAOP의 구현 목적은 엔터프라이즈 어플리케이션에서 주로 사용되는 핵심적인 기능에 AOP의 장점을 살려 이를 Spring 내에서 사용하는 것이기 때문에 다른 AOP와 같은 AOP의 복잡한 전체 기능을 굳이 다 필요로 하지 않는다. 프록시 기반의 SpringAOP는 SpringIoC/DI와 매우 긴밀하게 연동이 된다. 따라서 SpringAOP를 사용하는 방법은 Spring 내에 ProxyBean을 설정해서 쉽게 사용할 수 있다. JDK의 표준 기능만을 사용하기 때문에 특별한 빌드 과정이 필요없고 클래스 로더를 변경한다거나 하는 번거로운 작업이 없다. 대신 JoinPoint가 종류가 메소드 기반으로 제한되나 대부분의 엔터프라이즈 어플리케이션에서 필요로 하는 주요 AOP 기능들을 메소드 호출을 기반으로 충분히 처리가 가능하기 때문에 SpringAOP는 그 제한된 AOP 기능에도 불구하고 현장에서 가장 빠른 속도로 적용되어 사용되는 AOP 솔루션 중의 하나이다. SpringAOP는 Advice와 Pointcut을 모두 표준 자바 클래스로 작성할 수 있다. 필요에 따라서 Pointcut은 설정 파일 내에서 Pointcut FactoryBean을 이용해서 정규식으로 표현이 가능하다. SpringAOP의 최대 단점은 복잡한 Proxy 설정 구조이다. Spring Bean을 정의한 파일에서 Proxy를 정의한 부분의 다른 XML기반의 AOP에 비해서도 복잡한 편인데 이 경우 SpringAOP가 지원하는 AutoProxyingCreatorBean 등을 이용하면 설정 코드를 매우 단순하게 작성하는 것이 가능하다.
Trackback 0 and Comment 0