AOP Alliance (Java/J2EE AOP standards)

2023. 5. 10. 14:14Spring Framework/Spring AOP

AOP Alliance

AOP Alliance aopalliance.sourceforge.net

aopalliance 1.0 javadoc (aopalliance)

 

Introduction

이 문서의 목적은 AOP Alliance 프로젝트를 소개하는 것입니다. 그 목표, 철학, 제공해야 할 답변, 그리고 제공하지 말아야 할 것들에 대해 다루고자 합니다. 이 문서는 AOP Alliance의 다른 구성원들과 논의를 통해 우리가 여기서 무엇을 하고 있는지에 대한 공통된 견해를 도출하기 위해 추가 논의가 필요한 초안 제안서입니다. 또한, 목록에서 논의 중에 흥미로운 점이 나오면 이 문서에 추가되어야 합니다.

이 문서는 백서(white paper)로, AOP Alliance 구성원들이 내부적으로 사용할 수 있을 뿐만 아니라 외부 사람들에게 AOP Alliance가 무엇인지에 대한 통찰과 이해를 제공하는 데에도 사용될 수 있습니다.

1장에서는 AOP Alliance의 목표를 일반적인 용어로 설명하려고 합니다. 우리의 동기는 AOP가 J2EE 기반 솔루션과 같은 것들을 개선할 수 있다는 사실에서 비롯됩니다. 우리가 표준화된 API 세트를 정의할 수 있다면, 기존 솔루션에 AOP를 통합하거나 기존 AOP 도구를 사용하여 AOP 환경을 구축하는 것이 가능해질 것입니다. 2장에서는 애스펙트 지향 환경을 위한 제안된 아키텍처와 API에 대한 개요를 제공합니다. AOP Alliance가 명시해야 할 API가 무엇인지 추측해 보았습니다. 마지막으로, 3장에서는 식별된 구성 요소들과 AOP 환경 내에서의 그들의 역할에 대해 자세히 설명합니다.

AOP Alliance goals

AOP Advantages: The J2EE Case

애스펙트 지향 프로그래밍(AOP)은 애플리케이션을 설계하고 프로그래밍하는 데 있어 훌륭한 방법입니다. AOP는 기존 기술(EJB 등)이 제공하는 것보다 더 나은 해결책을 제시합니다.

J2EE는 AOP Alliance의 혜택을 받을 수 있는 전형적인 대상 환경이지만, 유일한 대상은 아닙니다. 실제로 J2EE 환경은 영속성이나 트랜잭션과 같은 기술적 문제를 처리할 수단을 제공함으로써 일부 문제를 부분적으로 해결합니다. 그러나 J2EE 아키텍처는 특정 요구와 관련된 새로운 기술적 관심사를 쉽게 추가할 만큼 유연하지 않습니다. 또한, 필요하지 않거나 더 가벼운 솔루션이 선호되는 경우 하나의 솔루션을 제거할 수 있는 기능이 있으면 유용할 것입니다.

AOP는 새로운 기술적 관심사(crosscutting concerns)를 구축하고 이를 애플리케이션 내에 유연하고 모듈화된 방식으로 연결할 수 있는 일반적인 수단을 제공합니다. J2EE에 일부 AOP 개념을 적용하면 J2EE의 사용이 훨씬 간단해질 수 있습니다. 예를 들어, 일반 자바 객체(POJO)를 EJB 대신 사용할 수 있습니다. 따라서 J2EE에 완전한 AOP를 쉽게 적용할 수 있다면 J2EE의 사용성을 크게 향상시킬 것입니다. 또한, J2EE 준수 애플리케이션 서버에 훨씬 더 많은 기능을 제공할 것입니다.

The Current Brakes To AOP

AOP는 인기를 얻고 있습니다. 그러나 대부분의 AOP 도구들은 특정 환경에서 사용되도록 설계되지 않았습니다(주로 대부분의 도구가 실험 목적에서 설계되었기 때문입니다). 따라서 특정 환경에서 AOP를 사용하려고 할 때, 예를 들어, 그 환경이 이미 AOP 도구 구현과 호환되지 않는 내장된 애스펙트를 지원하는 경우, 몇 가지 문제에 직면할 수 있습니다.

이 문제는 AOP가 제대로 작동하기 위해 애플리케이션의 객체나 클래스를 수정해야 하기 때문에 발생합니다. 이러한 객체 수정 로직은 AOP 도구의 특정 부분인 위버(weaver)에 의해 구현됩니다. 위버는 특정 환경에 잘 맞을 수 있지만, 다른 환경에서는 중요한 시스템 속성을 손상시킬 수 있습니다. 예를 들어, Gregor와 Rickard 사이의 AOP Alliance 목록에서의 흥미로운 논의는 AspectJ의 위버 구현이 일부 환경에서 분산 및 영속성 기능을 갖춘 환경에 잘 맞지 않는다는 것을 보여준 것 같습니다.

The AOP Alliance Claim

여기 있는 대부분의 사람들은 완벽한 시스템을 믿지 않습니다. 우리는 시스템이 항상 특정 문제와 환경에 적합하다고 생각하며, 다른 문제나 환경에는 반드시 적합하지 않을 수도 있습니다. 이것이 바로 J2EE와 같은 복잡한 환경에서 사용할 수 있는 AOP 도구의 경우에 해당합니다. 직면한 문제에 따라 AOP의 특정 구현이 유용할 수 있습니다.

이미 AOP나 AOP 관련 기술(예: 제네릭 프록시, 인터셉터, 바이트코드 변환기)의 많은 특정 구현들이 존재합니다. 예를 들어, 다음과 같은 것들이 있습니다:

  • AspectJ: AO 소스 수준(및 바이트코드 수준) 위버. 새로운 언어.
  • AspectWerkz: AO 프레임워크(바이트코드 수준의 동적 위버 + XML에서의 구성).
  • BCEL: 바이트코드 변환기.
  • JAC: AO 미들웨어(바이트코드 수준의 동적 위버 + 구성 + 애스펙트). 프레임워크.
  • Javassist: 고수준 API를 가진 바이트코드 변환기.
  • JBoss-AOP: 인터셉션 및 메타데이터 기반 AO 프레임워크(JBoss 애플리케이션 서버에서 실행 + 독립 실행형 버전).
  • JMangler: 번역을 위한 구성 프레임워크가 있는 바이트코드 변환기.
  • Nanning: AO 위버(프레임워크).
  • Prose: AO 바이트코드 수준의 동적 위버(프레임워크).

우리는 이러한 구현들이 좋은 구현이나 나쁜 구현이 있는 것이 아니라, 특정 문제/환경에 적합한 구현이 있을 뿐임을 반영한다고 생각합니다.

따라서 AOP Alliance의 목표는 새로운 AOP 모델을 제시하거나, 모든 경우에 작동하거나 특정 J2EE 애플리케이션 서버에서 작동할 훌륭한 AOP 구현을 제공하는 것이 아닙니다. 오히려 AOP Alliance의 목표는 모든 기존 구현들이 동일한 핵심 언어를 사용하도록 하여 다음을 가능하게 하는 것입니다:

  • 기존 AOP 구성 요소를 재사용함으로써 재구축을 피하기,
  • 특정 대상 환경(일반적으로 J2EE 환경)에 맞게 기존 AOP 구성 요소의 적응을 간소화하기,
  • 공통의 루트 AOP API를 통해 애스펙트 재사용을 간소화하기,
  • AOP 기능을 통합하려는 개발 도구의 구현을 간소화하기.

Aspect-Oriented Architectures

A Common Architectural Vision

공통된 AOP(Aspect-Oriented Programming) 모델과 구현 방식에 합의하는 것은 어렵습니다. 그 이유는 사용 맥락과 환경에 너무 밀접하게 연결되어 있기 때문입니다. 예를 들어, 순수 자바 접근 방식과 J2EE 준수 접근 방식에서는 구현이 다를 수 있습니다. 하지만, 우리는 Aspect-Oriented Environments(AOE)에 대해 공통된 아키텍처적 비전에 합의하는 것이 가능하다고 생각합니다.

실제로, Aspect-Oriented Environment(AOE)를 구축할 때 설계자들은 아키텍처를 정의해야 합니다. 대부분의 기존 AOE에서 아키텍처는 시스템의 기본 기능을 구현하는 몇 가지 기본 모듈/구성 요소/API를 정의하고 결합합니다. 기존 도구들을 살펴보면, 공통 구성 요소들을 식별할 수 있습니다(즉, 해당 아키텍처에서 유사한 기능을 제공하지만, 반드시 동일한 구현 기술을 사용하는 것은 아님). 예를 들어, JBoss의 위버는 Javassist를 사용하여 클라이언트 측에서 인터셉션 메커니즘을 구현하는 반면, JAC의 위버는 BCEL을 사용하여 서버 측에서 인터셉션 메커니즘을 구현합니다. 동일한 효과를 내기 위해 JIT 컴파일러를 간섭하는 다른 기술도 사용할 수 있습니다. 이들 모두는 환경에 크게 의존합니다.

다음 섹션에서는 AOE에 유용할 수 있는 구성 요소들을 추출해 보겠습니다. 이러한 구성 요소들은 맥락에 따라 달라지는 AOE를 구축하는 데 사용될 수 있습니다.

Aspect-Oriented Environment

AOE라는 용어는 AOP를 어떤 방식으로든 지원하는 모든 환경을 의미합니다. 예를 들어, JBoss AOP는 AOE에 해당하지만, 내장된 애스펙트를 가진 J2EE 애플리케이션 서버도 축소된 형태의 AOE로 간주될 수 있습니다.

 

A 3-Layer Typical Architecture

그림 1.

전형적인 아키텍처는 그림 1에 표시된 것처럼 그릴 수 있습니다. 이 단순화된 다이어그램에는 몇 가지 구성 요소(사각형)와 구성 요소의 API를 사용할 수 있는 몇 가지 핵심 로직(둥근 상자)이 포함되어 있습니다(굵은 화살표). 이 아키텍처는 도표의 상단에 초기 AO(애스펙트 지향) 프로그램을 실행하기 위해 설계되었습니다. 이 아키텍처는 참조 아키텍처가 아니라 하나의 가능한 아키텍처임을 유의해야 합니다. 실제로 AO 아키텍처의 다양한 핵심 구성 요소를 구성할 수 있는 여러 가지 가능성이 존재합니다.

이 아키텍처는 세 가지 계층으로 나눌 수 있습니다:

  1. 대상 플랫폼에서 위빙(AOP의 주요 과정)을 구현하기 위한 기본 구성 요소를 제공하는 저수준 계층,
  2. AOP의 원래 의미에 따라 기본 구성 요소와 AO 의미론을 구현하는 로직을 제공하는 고수준 계층(대상 플랫폼에 따라 다름),
  3. UI를 광범위한 의미로 포함하는 개발 수준의 계층(언어로 지원될 수 있으며, 모델링 도구일 수 있음)과 AO 프로그램을 신뢰할 수 있도록 돕기 위한 기타 도구(예: 타입 검사, 시각화 도구, 디버거 등).

What Shall AOP Alliance Specify Here?

앞서 언급한 바와 같이, AOP Alliance의 목표는 새로운 모델을 제공하거나 기존 도구의 더 나은 구현을 제공하는 것이 아닙니다. 사실, AOP Alliance의 목표는 공통적인 애스펙트 지향 환경(AOE) 구현에서 식별된 구성 요소에 대해 표준화된 API를 명시하는 것입니다. 우리가 이것을 성공적으로 수행한다면, AOP를 사용하고자 하는 컨텍스트에 가장 적합한 구성 요소를 통합하여 기존보다 더 나은 AOE를 구축할 수 있을 것입니다. 특히, J2EE 애플리케이션 서버와 같은 복잡한 환경에서도 AOP의 최고 장점을 사용할 수 있어야 합니다.

따라서 도표 1을 참조하면, AOP Alliance의 역할은 식별된 구성 요소의 API를 정의하는 것이어야 합니다. 가장 중요한 구성 요소는 저수준의 것들인데, 그 구현 방식이 AOE를 사용할 수 있는 환경에 영향을 미치기 때문입니다. 일부 기술적 특성은 결과 시스템의 속성에 깊은 영향을 미칠 수도 있습니다(예: 애스펙트가 동적으로 위빙/언위빙될 수 있는지 여부, 시스템이 배포에 대해 확장 가능한지 여부, 시스템이 영속성 또는 트랜잭션과 같은 내장 애스펙트와 공존할 수 있는지 여부 등). 그러나 고수준 구성 요소들도 IDE, 디버거, 모델링 도구와 같은 도구들에 매우 흥미로울 수 있습니다. 공통적인 AOP 개념 조작 API를 갖추면, 도구들이 서로 다른 환경에서 여러 AOP 구현을 더 잘 지원할 수 있게 될 것입니다.

AOP Alliance는 일부 구성 요소에 대해 기존 도구를 사용하여 참조 구현을 제공할 수 있습니다. 그러나 정의된 API의 구현은 기존 도구들(대부분의 도구 제작자들이 Alliance에 참여하고 있음)이 직접 제공하는 것이 더 나을 것입니다. 이러한 구현은 API의 정확성을 검증할 것입니다.

AOP Alliance는 위빙 로직과 구성 로직을 다루지 않을 것입니다. 이는 AOE 구현에 따라 크게 달라지기 때문입니다. 그러나 우리는 API를 사용하여 AOE를 구축하는 방법을 보여주기 위해 몇 가지 참조 구현을 제공해야 합니다.

마지막으로, AOP Alliance는 세 번째 계층(개발 수준)을 다루지 않을 것입니다. 우리는 AOP 도구가 우리의 API를 구현할 때, 개발 도구 구현자들이 우리의 API를 사용할 수 있도록 해야 합니다.

AOP Alliance Components

이제 AOP Alliance 핵심 구성 요소의 전체적인 그림을 살펴보겠습니다. 경고: 이 구성 요소들은 AOP Alliance가 명시해야 할 API에 대한 첫 번째 제안 초안입니다. 이들 중 일부는 제거될 수 있으며, 일부는 추가될 수 있습니다. 이들 중 일부는 이미 Java 인터페이스로 명시되기 시작했다는 점에 유의하세요.

Low-Level Components

저수준 구성 요소는 매우 중요합니다. 왜냐하면 전체 AOE(Aspect-Oriented Environment)가 이들에 의존하여 구현되기 때문입니다. 이러한 구성 요소들이 어떻게 구현되는지는 매우 중요하며, 성능, 확장성, 통합 능력 또는 보안과 같은 시스템의 속성에 큰 영향을 미칠 수 있습니다.

Reflection

리플렉션 API는 모든 AOE(Aspect-Oriented Environment)에 매우 중요합니다. 사실, 위버(weaver)는 어드바이스나 인트로덕션을 적용하기 위해 기본 프로그램의 클래스를 조사(introspect)해야 합니다. 예를 들어, 어떤 포인트컷이 클래스의 모든 메서드에 어드바이스를 적용해야 한다고 지정한 경우(정규 표현식이나 ALL 키워드를 사용하여), 위버는 실제로 어드바이스가 필요한 메서드 목록을 명시적으로 알기 위해 리플렉션 API를 사용해야 합니다.

위빙 과정이 런타임에 수행될 때는 SUN의 java.lang.reflect 구현이 AOE를 구축하는 데 충분할 수 있습니다. 그러나 대부분의 기존 시스템에서는 위빙 과정이 컴파일 타임 또는 클래스 로드 타임에 발생합니다. 이러한 경우, 특정 리플렉션 API 구현이 필요합니다. AOP Alliance에 따르면, AOE의 실행 컨텍스트에 따라 기본 구현을 변경할 수 있도록 이 API를 표준화하는 것이 매우 중요합니다.

Program Instrumentation

위버의 관점에서 리플렉션이 위빙된 프로그램에 대한 읽기 접근이라면, 인스트루멘테이션은 쓰기 접근입니다. 그러나 AOP에서 허용되는 프로그램 수정은 제한된 수정 집합입니다. 허용되는 수정은 초기 프로그램의 기존 구조에 대해 점진적인 수정이므로, 애스펙트들이 올바르게 함께 구성될 수 있습니다. 이러한 종류의 점진적인 수정을 이전 논의에서 인스트루멘테이션이라고 부릅니다.

인스트루멘테이션에 대한 표준 API는 없습니다. 하지만 리플렉션과 마찬가지로, 인스트루멘테이션은 런타임, 컴파일 타임, 또는 로드 타임에 발생할 수 있습니다. 게다가 각 범주마다 컨텍스트와 AOE 환경에 따라 다른 구현이 수행될 수 있습니다(예를 들어, 인스트루멘테이션은 소스 코드나 바이트코드에서 직접 수행될 수 있습니다). 따라서 AOE 요구 사항에 따라 기본 구현을 변경할 수 있도록 인스트루멘테이션 API를 표준화하는 것이 중요합니다.

Interception Frameworks

AOE(Aspect-Oriented Environments)를 구축하는 데 매우 유용할 수 있는 또 다른 유형의 기본 구성 요소는 인터셉션 프레임워크입니다. Java는 동적 프록시를 통해 인터셉션을 위한 표준 API/프레임워크를 제공합니다. 그러나 투명성, 성능 등에서 여러 가지 개선이 다른 구현을 통해 이루어질 수 있습니다(대부분이 인스트루멘테이션 API를 사용합니다). 따라서 명확한 의미를 가진 표준 인터셉션 API/프레임워크를 정의하는 것도 흥미로운 일입니다.

인터셉션 프레임워크는 AOP 모델의 around 어드바이스를 매우 쉽게 구현할 수 있게 해주는 많은 장점이 있습니다. 또한, 이 프레임워크들은 독립적으로 사용할 수 있으며, 대부분의 경우 순수 자바로 작성되었음에도 불구하고 상당히 명확한 AOP 스타일의 코드를 제공합니다. 이러한 이유로 여러 프로젝트와 환경(예: J2EE 애플리케이션 서버, JBoss 참고)에서 여러 인터셉션 프레임워크가 구현되었습니다. 따라서 AOP Alliance는 이 중요한 AOP 도구 모음을 표준화하기 위해 추상적인 인터셉션 프레임워크를 제공해야 합니다.

Metadata Handling

메타데이터 처리는 AOE(Aspect-Oriented Environments)를 구현할 때 특히 인터셉션 프레임워크와 결합될 경우 유용합니다. 메타데이터 처리를 통해 위버는 클래스의 시맨틱을 비침투적 방식으로 확장할 수 있습니다. 대부분의 메타데이터 구현은 동적성을 허용하기 때문에, 동적 구성/재구성에도 사용할 수 있습니다.

비록 JDK 1.5가 메타데이터에 대한 표준 구현을 제공할 것이지만, 여러 구현을 허용하는 표준 API를 제공하는 것이 유용할 것입니다. 이러한 API는 배포, 직렬화와 같은 환경 특수성을 고려할 수 있으며, 기본 구현에서 제대로 처리되지 않을 수 있는 부분도 다룰 수 있습니다.

Class Loading Frameworks

많은 AOE(Aspect-Oriented Environments)에서 바이트코드 수준의 조작이 필요합니다. 이는 인터셉션 프레임워크를 구현하거나, 프로그램에 대한 위버의 인스트루멘테이션을 직접 구현하는 데 사용할 수 있습니다. 일부 경우에는 AOP 인스트루멘테이션이 상당히 간단하기 때문에 클래스 로드 시점에서 이러한 바이트코드 수준의 조작이 수행될 수 있습니다. 따라서 대부분의 AOE는 Java의 유연한 클래스 로딩 아키텍처를 사용합니다.

그러나 여러 환경에서도 클래스 로더를 사용하여 고유의 기능을 구현합니다. 예를 들어, 분산 환경에서는 특정 클래스 로더를 사용하여 스텁을 생성할 수 있습니다. 이러한 환경에서는 AOE의 클래스 로딩 메커니즘이 클래스 로더의 비호환성으로 인해 시스템 충돌을 일으킬 수 있습니다.

따라서 우리는 서로 다른 환경에서 오는 다양한 클래스 로더가 안전한 방식으로 협력할 수 있도록 충분히 유연한 클래스 로딩 프레임워크를 표준화하는 것이 중요할 수 있다고 생각합니다.

High-Level Components

고수준 구성 요소를 표준화하는 것은, 세 번째 계층(개발 계층)에서 정의된 도구들이 AOP에 대해 전반적으로 더 나은 지원을 제공할 수 있도록 하기 위해 중요합니다.

AOP API

우리의 AOP API의 목표를 설명하는 데 있어 Gregor의 말을 인용하는 것이 좋을 것입니다: "분명히 우리는 AOP 도구들 사이에서 불필요한 불일치를 피하기 위해 할 수 있는 모든 것을 해야 합니다. 실제로 표준화하기에는 아직 너무 이르며, 의미 있는 변화를 위한 여지가 필요합니다. 그러나 불필요한 변화는 분명히 제거할 가치가 있습니다."

따라서 우리의 AOP 모델은 새로운 모델이 아닐 것입니다. 우리는 단지 현재 존재하는 모델들이 공통적으로 가지고 있는 것을 결합하려고 할 것입니다. AspectJ 모델이 가장 완성도가 높은 모델임은 의심의 여지가 없으며, 이를 지원하는 도구들도 이미 몇 가지 있습니다. 그래서 우리는 여기에서 AspectJ의 일부를 채택할 가능성이 큽니다.

Configuration API

많은 애스펙트는 범용적인 방식으로 구현될 수 있습니다. 이는 애스펙트 기능을 적용하고자 하는 모든 프로그램에서 잠재적으로 재사용 가능한 로직을 구현한다는 것을 의미합니다. 대부분의 경우, 이러한 애스펙트 재사용 과정은 범용 애스펙트의 파라미터화를 포함합니다(예: 범용적인 영속성 애스펙트에 어떤 클래스가 영속성을 가져야 하는지, 어떻게 처리해야 하는지를 지정하는 것). AspectJ에서는 추상 애스펙트를 서브클래싱하여 이를 수행할 수 있습니다. 하지만 외부 도구(예: 전처리기)를 사용하여 이를 수행할 수도 있습니다. J2EE 환경에서는 내장된 애스펙트(EJB 컨테이너의 기술적 관심사)의 구성 프로세스가 XML 배포 파일로 파라미터화됩니다. JBoss/AOP 및 기타 프레임워크에서는 XML 파일을 사용하여 구성을 할 수 있습니다. JAC에서는 Java 프로그램에서 애스펙트 구성 API를 사용하거나 특정 스크립트 언어와 같은 언어를 사용하여 구성을 할 수 있습니다.

구성 API를 표준화할 수 있다면 매우 유용할 것입니다. 이는 개발 도구에 대한 AOE 통합을 더 쉽게 만들어줄 것입니다. 또한, AOE 간에 특정 구성을 재사용하는 것을 촉진할 것입니다(예: AspectJ와 JBoss/AOP).

애스펙트를 AOE 간에 이식 가능하게 만드는 것은 잠재적으로 중요한 차이점들 때문에 비현실적일 수 있음을 유의해야 합니다. 하지만 애스펙트 구성을 이식 가능하게 만드는 것은 덜 비현실적이며, 이는 AOE 상호운용성으로 나아가는 첫걸음이 될 수 있습니다.

Conclusion

이 문서는 AOP Alliance 프로젝트의 이유를 설명하고 일부 목표를 명시하려고 시도합니다. 제가 이해한 바에 따라 목록에 있는 많은 사람들을 대표하여 이야기하려고 했습니다. 현재로서는 다소 불명확하며, 전체적인 그림만을 그릴 뿐입니다. 아마도 일부 사람들은 동의하지 않거나 실망할 수도 있습니다. 우리가 이곳에서 진정으로 원하는 것이 무엇인지에 대해 좋은 논의를 나눌 수 있다면 정말 좋을 것입니다.