레퍼런스 AOP(Aspect Oriented Programming)

황제낙엽 2007.06.03 03:18 조회 수 : 39 추천:142

sitelink1 http://blog.naver.com/leeyd81/100033771390 
sitelink2  
sitelink3  
extra_vars6  

자바 언어에 AOP를 가져다 주는 AspectJ

Nicholas Lesiecki
기술지원팀 리더, eBox, Inc.
2002년 1월

영역 지향 프로그래밍(Aspect-oriented programming : AOP)은 프로그래머들이 로깅과 같이 일반적인 책임 구분을 넘어서는 행위인 횡단적 사항을 모듈화하도록 해주는 새로운 프로그래밍 기법이다. AOP는 여러 클래스에 영향을 미치는 행위들을 재사용 가능한 모듈로 캡슐화시키는 영역 (aspect)을 제공한다. XeroX PARC사가 최근 출시한 AspectJ로 자바 개발자들은 이제 AOP가 제공하는 모듈화를 이용할 수 있게 되었다. 이 글은 AspectJ를 소개하고 이를 사용하여 얻을 수 있는 설계상의 이점을 설명한다.

AOP는 일반적인 프로그램들이 종종 하나의 프로그램 모듈, 혹은 심지어는 여러 개의 밀접하게 관련된 프로그램 모듈들에도 자연스럽게 맞추어지지 않는 행위를 보여준다는 인식에서 출발하였다. AOP의 개척자들은 이런 유형의 행위를 횡단적(crosscutting)이라고 불렀는데, 주어진 프로그래밍 모델에서 일반적인 책임 구분을 넘어서기 때문이다. 예를 들어, 객체 지향 프로그래밍에서 모듈화의 기본 단위는 클래스이며, 횡단적 관심사는 여러 클래스에 걸쳐 있는 관심사를 말한다. 전형적인 횡단적 관심사에는 로깅, 문맥 의존형 에러 처리, 성능 최적화 및 설계 패턴 등이 포함한다.

횡단적 관심사를 해결하는 코드에 관해 작업했던 적이 있다면, 여러분은 모듈화의 부족 때문에 발생하는 문제들을 알고 있을 것이다. 횡단적 행위들의 구현이 분산되어 있기 때문에, 개발자들은 이러한 행위의 추론, 구현 및 변경이 어렵다는 것을 알게 된다. 예를 들어, 로깅을 위한 코드는 주 책임이 따로 있는 코드들과 얽히게 된다. 해결되어야 하는 사항의 복잡성과 범위에 따라 결과로 나오는 얽힘의 상태는 사소한 것에서부터 중대한 것까지 어느 것이 될 수도 있다. 한 애플리케이션의 로깅 정책을 바꾸면 수백 줄의 코드를 수정해야 할 수 있고, 이는 가능하다고는 해도 매우 짜증나는 일이 될 것이다. 다른 측면에는 AOP가 만들어진 사례 중 하나가 있다. "Aspect-Oriented Programming"이라는 글에서 AspectJ 저작자들은 768 라인으로 된 프로그램을 35,213 라인으로 만들었던 성능 최적화에 관해 기술하고 있다. 이 코드를 영역 지향 기법으로 다시 작성한 결과 성능상의 이점은 대부분 유지하면서 코드를 1,039 라인으로 줄일 수 있었다.

AOP는 횡단적인 사항들의 광범위한 구현을 하나의 단위로 모으는 모듈화의 또다른 유형을 촉진함으로써 객체 지향 프로그래밍을 보완하게 된다. 이러한 단위들을 영역(aspects)이라고 부르며, 이 때문에 영역 지향 프로그래밍이라는 이름이 붙었다. Apsect 코드들을 구획화함으로써 횡단적인 사항들을 다루기가 쉬워진다. 시스템의 aspect들은 컴파일 시에 변경, 삽입, 삭제될 수 있고 심지어는 재사용도 가능하다.

예제를 통해 배우기

AOP에 대해 좀 더 잘 이해하기 위해서 Xerox PARC사가 내놓은 자바 프로그래밍 언어의 aspcect 지향 확장판인 AspoectJ를 살펴보자. 우리 예에서, 우리는 로깅을 수행하기 위해 AspectJ를 사용할 것이다. 이 예는 서버측 자바 컴포넌트 테스트를 간편하게 해주는 오픈 소스의 Cactus 프레임워크에서 가져온 것이다. Cactus v.1.2는 AspectJ 없이 작성되었으며, 일반적인 메소드는 아래 Listing 1에 나온 것과 유사하다.:

Listing 1. 모든 메소드속에 수작업으로 삽입된 로그 호출
public void doGet(JspImplicitObjects theObjects) throws ServletException
{
  logger.entry("doGet(...)");

  JspTestController controller = new JspTestController();
  controller.handleRequest(theObjects);

  logger.exit("doGet");
}
 

프로젝트 코드 표준화의 일부로써 모든 개발자는 이 코드들을 그가 작성하는 모든 메소드에 삽입하라는 요구를 받았다. 개발자들은 또한 각 메소드의 매개변수들을 로깅해야 했다. 프로젝트 관리자들의 진땀 빼는 코드 검토가 이루어지지 않는다면 이러한 종류의 표준화는 지켜지기 어렵다. 버전 1.2에는 약 80개의 개별적인 로그 호출이 15개 클래스들에 걸쳐 존재하였다. 이 프레임워크의 버전 1.3에서 이 80여 개의 호출들은 메소드의 시작부터 끝에 걸쳐 매개변수와 결과값을 자동으로 로깅하는 하나의 aspect로 교체되었다. Listing 2는 이 aspect의 매우 단순화된 버전을 포함하고 있다.(예를 들어 필자는 매개변수와 결과값 로깅 부분을 뺐다)

isting 2. 모든 메소드에 자동으로 적용된 로그 호출


public aspect AutoLog{
 
  pointcut publicMethods() : execution(public * org.apache.cactus..*(..));

  pointcut logObjectCalls() :
    execution(* Logger.*(..));
   
  pointcut loggableCalls() : publicMethods() && ! logObjectCalls();
   
  before() : loggableCalls(){
    Logger.entry(thisJoinPoint.getSignature().toString());
  }
   
  after() : loggableCalls(){
    Logger.exit(thisJoinPoint.getSignature().toString());
  }
}

 

이 예를 자세히 분석하여 aspect가 무슨 일을 하는지 살펴보자. 여러분은 먼저 aspect 선언이 눈에 띌 것이다. Aspect들은 이들의 선언에서 클래스와 유사하며, 클래스와 마찬가지로 자바 유형을 정의한다. 이 aspect는 선언 외에 포인트컷과 어드바이스를 가지고 있다.

포인트컷과 결합 포인트

포인트컷을 이해하려면 결합 포인트가 무엇인지를 알아야 한다. 결합 포인트는 프로그램의 실행에 있어 잘 정의된 포인트들을 나타낸다. AspectJ에서 일반적인 결합 포인트에는 메소드 호출, 클래스 맴버 접근 및 예외 처리 블럭의 수행등이 포함된다. 결합 포인트들은 다른 결합 포인트들을 가지고 있을 수 있다. 예를 들어 하나의 메소드 호출은 결과값을 반환하기 전에 몇 개의 다른 메소드를 호출할 수 있다. 포인트컷은 정의된 기준에 따라 일련의 결합 포인트들을 가져오는 언어 구조를 가리킨다. 예제에서 publicMethods라는 첫번째 포인트컷은 rg.apache.cactus 패키지에서 모든 public 메소드 실행을 선택한다. execution은 기초적인 포인트컷이다 (int가 기초적인 자바 유형인 것과 마찬가지로). 자신의 구문 내에 정의된 서명(signature)과 일치하는 어떤 메소드라도 실행하도록 선택할 수 잇다. 서명은 와일드카드를 포함할 수 있다.; 예제에 있는 서명은 여러 개를 포함하고 있다. logObjectCalls이라고 불리는 두번째 포인트컷은 Logger 클래스 내의 모든 메소드 실행을 선택한다. 세번째 포인트컷인 loggableCalls은 && ! 표시를 사용하여 이전의 두 포인트컷을 결합시키는데, 이는 Logger 클래스에 있는 것은 제외하고 org.apache.cactus에 있는 모든 public 메소드를 선택한다는 의미이다. (로그 메소드를 로깅하는 것은 무한 반복으로 빠지게 될 것이다.)

어드바이스

이제 aspect가 로깅해야 하는 포인트들을 정의하였으므로 실제 로깅을 수행하기 위해 어드바이스를 사용한다. 어드바이스는 결합 포인트의 이전, 이후 혹은 수시로 수행되는 코드들을 가리킨다. 여러분은 어드바이스를 포인트컷과 상대적으로 정의하는데, "내가 로깅하고 싶은 모든 메소드의 호출 후에 이 코드를 수행시켜라"는 것과 유사하다. 어드바이스의 예는 아래와 같다.:


before() : loggableCalls(){
    Logger.entry(thisJoinPoint.getSignature().toString());
}
 

어드바이스는 Logger 클래스를 사용하는데, Logger 클래스의 entry 메소드와 exit 메소드는 아래와 같다.:


public static void entry(String message){
   System.out.println("entering method " + message);
}
 

이 예에서 logger로 전달된 String은 thisJoinPoint에서 나온 것인데, 이는 결합 포인트가 실행되는 런타임 문맥으로의 접근을 허용하는 특수한 반사 객체이다. Cactus가 사용하는 실제 aspect에서는 로깅된 각각의 메소드 호출로 전달되는 메소드 매개변수를 검색하기 위해 어드바이스가 이 객체를 사용한다. 로깅 aspect가 코드에 적용되었을 때 메소드 호출의 결과는 다음과 같다.:

Listing 3. AutoLog aspect의 출력
entering method: void test.Logging.main(String[])
entering method: void test.Logging.foo()
exiting method: void test.Logging.foo()
exiting method: void test.Logging.main(String[])
 

 

Around advice

Cactus 예제는 before()와 after() 어드바이스를 정의한다. 제 3의 어드바이스 유형인, around()는 애스펙트 라이터(aspect writer)에게 특별한 proceed() 신택스를 사용하여 조인 포인트(join point)의 실행 여부 및 실행 시기에 영향을 줄 수 있는 기회를 준다:


void around(): call(public void Hello.say()){
  if(Math.random() > .5){
      proceed();//go ahead with the method call
  }
  else{
      System.out.println("Fate is not on your side.");
  }
}
 
 

AspectJ를 사용해 개발하기

이제 여러분은 aspect 코드가 어떤 모습인지를 더욱 잘 알게 되었으므로, aspect를 작성하는 일로 우리의 관심을 돌려 보자. 다시 말해 "위의 코드를 어떻게 작동시킵니까"라는 질문에 답해보자.

aspect가 정식 클래스 기반 코드에 영향을 미치려면 aspect는 자신이 수정하는 코드에 엮어져야 한다. AspectJ를 사용해 이를 수행하려면 여러분의 클래스와 aspect 코드를 ajc 컴파일러로 컴파일해야 한다. ajc는 컴파일러로 혹은 precompiler로 작동할 수 있으며 유효한 .class 파일이나 .java 파일을 생성하는데, 여러분은 이를 컴파일하여 어떤 표준 자바 환경에서도 실행시킬 수 있다. (소규모 런타임 JAR을 추가하여)

AspectJ로 컴파일하기 위해서는 주어진 컴파일에 여러분이 포함시키고 싶은 소스 파일들(aspect와 클래스)을 명확하게 지정해야 할 것이다.--ajc는 javac가 하는 것처럼 관련 임포트를 찾기 위해 여러분의 클래스 경로를 검색하지 않는다. 표준 자바 애플리케이션에서 각 클래스는 다소 고립된 컴포넌트로 작동하기 때문에 이것은 말이 된다. 클래스가 올바르게 작동하려면 자신이 직접 참조하는 클래스만 있으면 된다. Aspect는 여러 클래스들에 걸쳐 있는 집합적인 행위를 나타낸다. 따라서 AOP 프로그램은 한 번에 하나의 클래스가 아닌 하나의 단위로 컴파일되어야 한다.

주어진 컴파일에 포함된 파일들을 지정함으로써 여러분은 또한 컴파일 시에 여러분 시스템의 다양한 aspect를 연결시키고 해제할 수 있다. 예를 들어, 앞에서 설명한 로깅 asptct를 컴파일에 포함시키거나 제외함으로써 애플리케이션 개발자는 Cactus 프레임워크에서 추적하는 메소드를 추가하거나 삭제할 수 있다.

AspectJ는 오픈 소스이다.


Xerox는 AspectJ를 Mozilla Public License 하에 이용할 수 있도록 만들었다. 이것은 오픈 소스 추종자들에게는 좋은 소식이다. 또한 가까운 미래에 AspectJ를 도입하려는 사람에게도 좋은 소식이다. 제품은 무료이고, 여러분이 중요한 버그를 발견했을 경우 소스 코드를 검토할 수 있다. 오픈 소스 기반은 또한 AspectJ의 소스가 시장에 나오기 전에 커뮤니티의 상당한 검토를 거쳤음을 의미한다.
 
AspectJ의 현재 버전이 가지는 중요한 한계점은 컴파일러가 소스를 가지고 있는 코드에만 aspect를 연결시킨다는 것이다. 다시 말해 여러분은 사전 컴파일된 클래스에 어드바이스를 추가하기 위해 ajc를 사용할 수 없다. AspectJ팀은 이런 한계점을 임시적인 것으로 간주하고 있으며, AspectJ 웹 사이트는 향후 버전 (공식적으로 2.0)에서 바이트코드 수정이 가능할 것이라고 약속하고 있다.

툴 지원

몇 개의 개발 툴들이 AspectJ 출시판의 일부로 포함되어 있다. 이는 AspectJ의 미래에 좋은 징조이다. AspectJ를 개발자에게 친근하게 만들려는 AspectJ 저작자들의 강한 의지를 반영한다. 툴 지원은 aspect 지향 시스템에서 특히 중요한데, 프로그램 모듈들이 그들이 전혀 알지 못하는 다른 모듈들의 영향을 받을 수 있기 때문이다.

AspectJ와 함께 출시된 가장 중요한 툴 중 하나는 aspect가 다른 시스템 컴포넌트들과 어떻게 상호작용하는지를 한 눈에 보여 주는 그래픽 기반의 구조 브라우저이다. 이 구조 브라우저는 독립형 툴로 사용할 수 있을 뿐 아니라 인기 있는 IDE의 플러그인으로도 사용가능하다. 그림 1은 앞에서 설명한 로깅 예제의 뷰이다.

그림 1. AspectJ와 함께 출시된 그래픽 기반의 구조 브라우저는 다른 무엇보다도 AutoLog가 어떤 메소드를 어드바이스할지를 보여준다.
 

구조 브라우저와 핵심 컴파일러에 부가하여 여러분은 AspectJ 웹사이트에서 aspect 인식 디버거, javadoc 툴, Ant task 및 Emacs 플러그인을 다운로드 받을 수 있다. 언어의 기능으로 되돌아가 보자.

클래스 구조에 영향 미치기 : Introduction

포인트컷과 어드바이스는 여러분이 프로그램의 동적인 실행에 영향을 미칠 수 있도록 한다.; Introduction은 aspect가 프로그램의 정적인 구조를 변경할 수 있도록 한다. Introduction을 사용하면 aspect는 클래스에 새로운 메소드와 변수를 추가할 수 있고 클래스가 한 인터페이스를 구현함을 선언할 수 있으며 또는 체크된 예외를 체크되지 않은 예외로 변환할 수 있다.

Introduction의 예

여러분이 영속 데이터의 캐시를 표시하는 객체를 가지고 있다고 가정해보자. 데이터의 "신선함"을 측정하기 위해 여러분은 그 객체에 timestamp 필드를 추가하여 객체와 이를 지원하는 저장 장치가 동기화되고 있는지를 쉽게 추적할 수 있도록 하려 한다. 그러나 객체는 비즈니스 데이터를 나타내기 때문에, 이 기계적인 세부 사항을 객체에서 분리하는 것이 바람직하다. AspectJ로 여러분은 Listing 4에 나온 구문을 사용하여 기존 클래스에 timestamping 기법을 추가할 수 있다.:

Listing 4. 기존 클래스에 변수와 메소드 추가하기
public aspect Timestamp {

  private long ValueObject.timestamp;

  public long ValueObject.getTimestamp(){
      return timestamp;
  }

  public void ValueObject.timestamp(){
      //"this" refers to ValueObject class not Timestamp aspect
      this.timestamp = System.currentTimeMillis();
  }
}

여러분은 어떤 클래스에서 이들을 선언할지 정해야 한다는 점을 제외하고는 (즉 ValueObject.timestamp), 정식 클래스 멤버에서와 거의 마찬가지로 introduce된 메소드와 멤버 변수를 선언할 수 있다.

혼합 형태의 상속

AspectJ는 여러분이 클래스뿐 아니라 인터페이스에 멤버를 추가할 수 있도록 하며, C++에 혼합 형태의 상속을 지원한다. 다양한 객체에 대해 timestamp 코드를 재사용할 수 있도록 Listing 4에 나온 aspect를 일반화하려면, TimestampedObject라는 인터페이스를 정의할 수 있고 introduction을 사용하여 구체적인 클래스 대신 인터페이스에 동일한 멤버와 변수를 추가할 수 있다. Listing 5에 이것이 나와 있다.

Listing 5. 인터페이스에 행위 추가하기 Adding behavior to an interface
public interface TimestampedObject {
    long getTimestamp();
 
    void timestamp();
}
//and
public aspect Timestamp {

    private long TimestampedObject.timestamp;

    public long TimestampedObject.getTimestamp(){
        return timestamp;
    }
 
    public void TimestampedObject.timestamp(){
        this.timestamp = System.currentTimeMillis();
    }
}
 

이제 여러분은 ValueObject가 여러분의 새로운 인터페이스를 구현할 수 있도록 하는 declare parents 구문을 사용할 수 있다. declare parents는 다른 AspectJ 유형 식과 마찬가지로 한번에 여러 개의 유형에 적용될 수 있다. :


declare parents: ValueObject || BigValueObject implements TimestampedObject;
 

이제 여러분은 TimestampedObject가 지원하는 작업들을 정의하였으므로, 적절한 환경이 발생했을 경우 포인트컷과 어드바이스를 사용하여 timestamp를 자동으로 업데이트할 수 있다. 이것은 어드바이스 내의 문맥에 어떻게 접근하는지 보여주기 때문에 이를 다음 섹션에서 다루도록 하겠다.

AspectJ의 다른 기능

포인트컷을 사용하여 여러분은 timestamp 처리된 객체가 어느 상황에서 업데이트되어져야 하는지를 쉽게 정의할 수 있다. Listing 6에 나온 것과 같이, Timestamp aspect의 추가 부분으로써 setter 메소드 호출을 한 후에는 객체에 대하여 timestamp 업데이트를 수행하고 있다.

Listing 6. 어드바이스 내의 문맥에 접근하기
pointcut objectChanged(TimestampedObject object) :
             execution(public void TimestampedObject+.set*(..)) &&
             this(object);
/*TimestampedObject+ means any subclass of TimestampedObject*/

after(TimestampedObject object) :  objectChanged(object){
        object.timestamp();
}
 

포인트컷은 호출된 settter를 가지고 있는 after()어드바이스가 사용하는 인자(이 경우에는 TimestampedObject)를 정의한다는 점에 유의한다. this() 포인트컷은 현재 실행 중인 객체가 괄호 내에 정의된 유형인 모든 결합 포인트를 구분한다. 메소드 인자, 메소드가 제시한 예외 및 메소드 호출의 타겟등 몇몇 다른 종류의 값이 어드바이스 인자에 바인딩될 수 있다.

커스텀 컴파일 에러

나는 커스텀 컴파일 에러가 AspectJ의 멋진 기능 중 하나임을 발견했다. 클라이언트 코드가 중개를 거쳐 worker 객체로 접근해야 하도록 하위 시스템을 격리시키기를 원한다고 해보자 (이 상황은 Facade 설계 패턴에서 등장한다). Listing 7에서와 같이, 여러분은 declare error 나 declare warning 구문을 사용하여 가능한 결합 포인트의 등장에 대한 ajc 컴파일러의 응답을 커스터마이즈할 수 있다.

Listing 7.커스텀 에러 정의하기
public aspect FacadeEnforcement {

  pointcut notThruFacade() : within(Client) && call(public * Worker.*(..));
   
  declare error : notThruFacade():
    "Clients may not use Worker objects directly.";
}

ajc가 컴파일 시에 이를 추적한다는 점을 제외하고는 within 포인트컷은 this()와 유사하다. (대부분의 포인트컷은 런타임 정보에 기반하여 구별될 수 있다.)

에러 처리

나는 자바 언어에서 체크된 예외 처리의 가치를 알고 있다. 그러나 종종 우회적인 방법으로써 좀 더 단순한 종류의 "이 예외는 런타임 예외로 바꾼다"라는 명령어를 원하였다. 내가 작성하고 있는 메소드는 예외에 대해서 의미 있는 응답을 가지고 있지 않는 경우가 많았고, 그럴 기회가 있다 하더라도 이 메소드를 사용할만한 사용자도 마찬가지였다. 나는 예외를 버리고 싶지도 않지만 모든 호출자를 통해 그 존재를 추적하고 싶지도 않았다. 이런 목적을 위해 try/catch 블록을 사용하는 교묘한 방법이 있긴 하지만 AspectJ의 declare soft만큼 훌륭한 것은 없다. Listing 8에 나온 클래스는 몇가지 SQL 작업을 시도하고 있다.:

Listing 8. 체크된 예외를 가진 클래스
public class SqlAccess {
   
    private Connection conn;
    private Statement stmt;
   

    public void doUpdate(){
        conn = DriverManager.getConnection("url for testing purposes");
        stmt = conn.createStatement();
        stmt.execute("UPDATE ACCOUNTS SET BALANCE = 0");
    }
   
    public static void main(String[] args)throws Exception{
        new SqlAccess().doUpdate();
    }
}
 

내가 AspectJ를 사용하고 있지 않거나 각 메소드 서명에서 예외를 선언하지 않는다면 체크된 SQLException (JDBC API의 거의 모든 메소드에서 주어지는)을 다루기 위해 insert try/catch 블록을 삽입해야 할 것이다. AspectJ로 나는 다음의 내부 aspect를 사용해 이것을 org.aspectj.lang.SoftException으로 자동적으로 다시 제공할 수 있다.

Listing 9. Softening exceptions
private static aspect exceptionHandling{
  declare soft : SQLException : within(SqlAccess);
 
  pointcut methodCall(SqlAccess accessor) : this(accessor)
    && call(* * SqlAccess.*(..));
   
  after(SqlAccess accessor) : methodCall  (accessor){
    System.out.println("Closing connections.");
    if(accessor.stmt != null){
        accessor.stmt.close();
    }
    if(accessor.conn != null){
        accessor.conn.close();
    }
  }
}
 

포인트컷과 어드바이스는 SQLAccess 클래스 내의 각 메소드가 수행 된 후에 그 메소드가 예외를 발생시키건 혹은 정상적으로 반환하던간에 상관없이 연결과 statement를 닫는다. 하나의 메소드를 위해 하나의 에러 처리 aspect를 사용하는 것은 아마도 지나친 단속일 것이다. 하지만, 연결과 statement를 사용하는 여타의 다른 메소드들을 추가하려 한다면, 에러 처리 정책도 이들에 적용되어야 할 것이다. 새로운 코드에 대한 aspect의 이러한 자동 적용은 AOP의 핵심적인 강점 중 하나이다: 새로운 코드의 작성자는 횡단적인 행위에 참가하기 위해 그 행위들을 알 필요가 없다.

결론

AspectJ가 사용할만한 가치가 있는가? Grady Booch는 AOP를 소프트웨어가 설계되고 작성되는 방식의 근본적인 변화가 시작됨을 종합적으로 표시하는 세 가지 움직임 중 하나로 설명하였다 (참고 자료에서 그의 "Through the Looking Glass"를 참조한다). 나는 그에게 동의한다. AOP는 객체 지향 언어와 다른 절차적 언어가 다루지 못했던 문제 영역을 해결한다. 내가 AspectJ를 알게 된 후 몇 주만에 나는 AspectJ가 내가 프로그래밍의 근본적인 한계라고 생각했던 문제들에 대해 훌륭하고 재사용 가능한 솔루션을 제공한다는 것을 발견했다. AOP는 내가 객체를 사용하기 시작한 이래 배운 가장 강력한 추상화라고 말할만하다.

물론 AspectJ는 배우는데 시간이 걸린다. 다른 언어나 언어 확장자와 마찬가지로 AspectJ의 모든 힘을 응용할 수 있기 전에 알아야 할 미묘한 점들이 있다. 그러나 학습이 그렇게 까다롭지는 않다. 나는 개발자 가이드를 읽고 몇 가지 예제를 작업해 본 후 내가 쓸만한 aspect를 구성할 준비가 되었음을 알았다. AspectJ는 새로운 방향으로 확장하기보다는 여러분의 프로그래밍 지식의 갭을 메우는 것처럼 자연스럽게 느껴진다. 몇몇 AspectJ 툴은 약간 까다롭긴 하지만 중대한 문제점은 만나지 못했다.

모듈화될 수 없는 것을 모듈화하는 AspectJ의 힘을 감안할 때 나는 이를 즉각 사용할만한 가치가 있다고 생각한다. 여러분의 프로젝트나 회사가 AspectJ를 생산 환경에 사용할 준비가 되어 있지 않다면 디버깅이나 계약 이행과 같은 개발 사항에 AspectJ를 쉽게 적용할 수 있다. 여러분 자신에게 부탁을 하고 이 언어 확장자를 체크해 보기 바란다.

참고 자료

www.aspectj.org에서 AspectJ와 관련 툴을 다운로드받을 수 있다. 이 사이트는 FAQ, 메일링 리스트, 훌륭한 문서들 및 AOP에 대한 다른 자원으로의 링크를 가지고 있다.


Grady Booch의 "Through the Looking Glass" (Software Development, July 2001)는 소프트웨어의 미래를 논의하고, 한 번에 여러 방식으로 작성될 수 있는 소프트웨어인 다각적 (multifaceted) 소프트웨어의 등장을 예측하고 있다. 이 글은 AOP를 프로그래밍 세계에서 첫번째 다각적 소프트웨어로의 움직임 중 하나로 언급하고 있다.


IBM의 연구팀에서 나온 또다른 다각적 방식이 Hyperspaces이다. Hyperspaces는 횡단적 사항의 캡슐화를 넘어서 그 사항을 여러 차원으로 분리하려고 시도한다. Hyper/J (Hyperspaces에 대한 자바 지원)는 요청에 따른 시스템 재모듈화를 제공한다.


IBM의 연구팀은 또한 주체 지향 프로그래밍(subject-oriented programming)에 포커스를 맞추고 있는데, 시스템의 독특한 "뷰"를 가지고 있는 클래스의 집합 혹은 클래스 부분인 주체 (subjects)를 제공한다. 주체는 작성 규칙에 따라 애플리케이션으로 작성된다.


asod.net 은 AOP 관련 정보의 총체적인 중앙 소스라고 할 수 있다. 이 사이트는 다른 AOP 시도들, 다른 언어에서의 aspect 구현, aspect와 유사한 소스 수정 및 aspect 이론에 관한 글로의 링크를 제공한다.


AOP에 대한 초기 글 중 하나인 "Aspect Oriented Programming" (PDF)는 새로운 프로그래밍 방식의 개발에 관한 초기 의견을 제공한다. 이 글의 서두에 언급된, 35,000 라인의 코드를 요구했던 성능 최적화가 aspect를 사용해 1,000라인으로 줄어든 예제가 이 글에서 사용되었다.


JavaWorld는 AOP를 소개하는 짧은 시리즈인 "I want my AOP."를 제공한다.


Eric Allen의 자바 코드 진단하기 컬럼은 횡단적인 사항들을 비일관적으로 처리하여 나타나는 많은 "버그 패턴"들을 다루고 있다. Allen은 OO 기법으로 이들을 최소화시키는 방법들을 설명한다. "버그 패턴 : 소개"는 반복적인 코드에서 나타나는 일반적인 버그 유형을 다루는데, 이들은 종종 OOP에서는 피할 수 없는 것들이다. 그는 예외와 관련한 "Null Flag 버그 패턴"에서 AspectJ를 구체적으로 언급하였다.


이 글에 나온 로깅 예제는 Jakarta의 Cactus객체에서 가져온 것이다.


developerWorks Java technology zone : 수많은 자바 관련 자료

  
목 차:
 
 
예제를 통해 배우기 
 
AspectJ를 사용해 개발하기 
 
클래스 구조에 영향 미치기 : Introduction
 
혼합 형태의 상속 
 
AspectJ의 다른 기능들 
 
결론 
 
참고 자료
 
필자 소개
 
기사에 대한 평가
 
 
 
관련 dW 링크:
 
Diagnosing Java Code
 
 
Subscribe to the developerWorks newsletter
 
US 원문 읽기 
 
 
 
 
 
 
 
필자 소개
Nicholas Lesiecki는 dot.com 붐 시대에 자바 프로그래밍의 세계에 입문하였고 그 이후 XP와 같은 민첩한 프로세스에서 오픈 소스 구축 및 테스팅 툴을 응용하기 위한 방법을 담은 매뉴얼인 Java Tools for Extreme Programming의 출판과 함께 XP와 자바 커뮤니티에서 탁월한 명성을 쌓아 왔다. 그는 현재 eBlox, Inc.의 고급 온라인 카탈로그 시스템인 storeBlox의 개발을 이끌고 있다. 그는 Tucson JUG에서 빈번하게 연설할 뿐 아니라 Jakarta의 Cactus 프로젝트 (서버측 단위 테스트 프레임워크)에 적극적으로 참여하고 있다.  
 

 

번호 제목 글쓴이 날짜 조회 수
공지 (확인전) [2021.03.12] Eclipse에서 Spring Boot로 JSP사용하기(Gradle) 황제낙엽 2023.12.23 0
공지 [작성중/인프런] 스프링부트 시큐리티 & JWT 강의 황제낙엽 2023.12.20 6
38 [POST] Spring MVC 구조 분석 황제낙엽 2024.01.17 1
37 OAuth 2.0 Resource Server - Spring Security OAuth2.0 황제낙엽 2023.12.27 1
36 [시리즈 강좌] 스프링부트로 웹서비스 구축하기 황제낙엽 2023.07.13 3
35 [Spring3.1.1] ResponseBody 한글깨짐 해결법 황제낙엽 2018.08.08 140
34 [Spring3.1.1][4] RestTemplate 한글 문제 황제낙엽 2018.08.08 89
33 [Spring3.1.1][3] RestTemplate 한글 문제 황제낙엽 2018.08.08 237
32 [Spring3.1.1][2] RestTemplate 한글 문제 황제낙엽 2018.08.08 113
31 [Spring3.1.1][1] RestTemplate 한글 문제 황제낙엽 2018.08.08 683
30 NamedParameterJdbcDaoSupport 몇가지 장점 황제낙엽 2007.11.27 101
29 Spring AOP - Pointcut 황제낙엽 2007.10.02 129
28 <spring:checkbox> tip! 황제낙엽 2007.10.01 378
27 스프링 2와 JPA 시작하기 (한글) 황제낙엽 2007.08.27 142
26 Spring 2.0의 XML확장기능 (3) 황제낙엽 2007.08.15 32
25 Spring 2.0의 XML확장기능 (2) 황제낙엽 2007.08.15 73
24 Spring 2.0의 XML확장기능 (1) 황제낙엽 2007.08.15 33
23 스프링의 구조별 기능 설명 황제낙엽 2007.06.26 42
22 자바지기 스프링 프레임웍 아티클 황제낙엽 2007.06.04 54
» AOP(Aspect Oriented Programming) 황제낙엽 2007.06.03 39
20 Spring MVC 어플리케이션 개발 <12> 간단한 조회 구현 방안 비교 황제낙엽 2007.05.27 31