AOP (Aspect Oriented Programing) Javajigi 3기 김선구
1. AOP 등장 배경 AOP는 OOP를 대체하기 위해 등장한 기술이 아니다. 초기 프로그래밍 (기계어, 어셈블러) 절차적 프로그래밍 (C, Pascal) 객체지향 프로그래밍 (C++, Java, C#) 관점지향 프로그래밍 (AspectJ) AOP는 OOP를 대체하기 위해 등장한 기술이 아니다. AOP는 OOP를 더욱 OOP답게 만들어 줄 수 있다. 프로그래밍 기술 변화의 흐름에 다른 차원의 관점(Aspect)을 제시 OOP가 해결 할 수 없는 부분에 대한 해법 제시
2. OOP의 문제점 (1) OOP에서 모듈화를 어렵게 하는 요소 – 인증, 로깅, … public class Board { public Bulletin read(User usr, int bulletinIndex) throws AuthenticationException // 사용자가 어떤 게시물을 요청했는지 로그 파일에 남긴다. // 사용자가 게시물을 읽기에 적절한 권한을 갖고 있는지 판단한다. // 게시판으로부터 게시물을 읽는다. // 사용자가 어떤 게시물을 읽었는지 로그 파일에 남긴다. // 읽어놓은 게시물을 반환한다. } public void write(User usr, Bulletin newBulletin) throws AuthenticationException // 사용자가 새로운 게시물을 쓰려 했음을 로그 파일에 남긴다. // 사용자가 게시물을 쓰기에 적절한 권한을 갖고 있는지 판단한다. // 게시판에 새로운 게시물을 써넣는다. // 사용자가 새로운 게시물을 썼음을 로그 파일에 남긴다. public void delete(User usr, int bulletinIndex) throws AuthenticationException // 사용자가 어떤 게시물을 지우려 했는지 로그 파일에 남긴다. // 사용자가 게시물을 지우기에 적절한 권한을 갖고 있는지 판단한다. // 게시판에 있는 게시물을 지운다. // 사용자가 게시물을 지웠음을 로그 파일에 남긴다. 핵심 비즈니스 로직 공통(지원) 모듈 (=Infrastructure) OOP에서 모듈화를 어렵게 하는 요소 – 인증, 로깅, …
2. OOP의 문제점 (2) ◆ 중복되는 코드 : 복사&붙이기에 의해 만들어진 여러 모듈에서 중복되는 코드의 문제점은 이미 잘 알려져 있다. 하지만 AOP를 사용하지 않은 대부분의 애플리케이션에서는 어떠한 추상화와 리팩토링을 통해서도 반복되는 코드를 피하기가 어렵다. ◆ 지저분한 코드 : 횡단 관심(Cross-Cutting Concern)과 관련된 코드들이 핵심기능 코드 사이사이에 끼어들어가 있기 때문에 코드가 지저분해지고 이에 따라 가독성이 떨어지며 개발자들의 실수나 버그를 유발하고 후에 코드를 유지보수하는데 큰 어려움을 준다. ◆ 생산성의 저하 : 문제영역에 대한 지식과 분석을 토대로 이를 구현해야 하는데 충실해야 하는 애플리케이션 개발자들이 자주 등장하는 횡단 관심을 구현한 코드를 함께 작성해야 하기 때문에 개발의 집중력을 떨어뜨리고 결과적으로 전체 생산성의 저하를 가져온다. 또 모듈별로 개발자들을 구분하고 분산시키는 것이 한계를 가질 수밖에 없다. ◆ 재활용성의 저하 : 이미 언급했듯이 OOP의 장점인 재활용성이 매우 떨어진다. ◆ 변화의 어려움 : 한번 작성된 시스템은 새로운 요구사항이 생겼을 경우에 전체적으로 많은 부분에 영향을 미치는 경우 쉽게 새로운 요구사항을 적용하기 힘들게 된다. 또 새로운 관심영역의 등장이나 이의 적용을 매우 어렵게 한다. 좋은 툴의 도움 없이는 리팩토링을 하는 것도 어렵게 된다.
3. Separation of Concern Separation of Concern - 문제 영역(Problem Domain)에 대한 독립적인 모듈로 분해 OOP에서는 분리된 모듈을 class로 작성 하지만 OOP를 적용해 class를 설계해도 분리할 수 없는 부분이 존재한다. AOP에서는 OOP를 통해 분리 할 수 없는 부분에 대해 관심 집중 Primary (core) Concern, Cross-cutting Concern Core Concern, Cross-cutting Concern이 하나의 프로그램(프로시져)에 들어가게 되면 프로그램을 이해하기 힘들고, Cross-cutting 코드가 산재되어 유지보수가 어렵다. 로그, 보안, 인증, 퍼시스턴스 등의 처리 방법과 환경이 바뀌어도 핵심 관심코드(Core Concern)은 변경이 일어나지 않도록 개발
4. AOP 개념 + Aspect : Advice + Point-Cut Primary Concern Advice + Weaving Cross-Cutting Concern Point Cut Aspect : Advice + Point-Cut Advice : Cross-cutting concern을 구현한 코드 Point-Cut : Advice를 Core Concern의 어느 위치에 둘지 정의 Weaving : Advice와 Core Concern을 구현한 코드를 Point-Cut 정보를 이용해 조합
5. AOP 동작 원리 Weaving : 핵심 비즈니스 코드(Core Concern)는 수정하지 않고 Cross-Cutting 코드를 삽입하는 작업 EJB와 같은 Container 또는 서버를 이용한 방법 : EJB는 트랜잭션과 보안, 오브젝트 풀링과 같은 횡단 관심 기능을 컨테이너를 통해 그 위에서 동작하는 EJB 모듈에 적용, 하지만 EJB는 제공할 수 있는 서비스가 매우 제한적이고 임의의 서비스 추가 등이 불가능하기 때문에 본격적인 AOP 방법으로 사용되기는 어렵다. 더군다나 컨테이너 위에서만 특별한 스펙에 따라 작성된 코드와만 연동해서 동작하기 때문에 POJO(Plain Old Java Objects) 기반의 일반 애플리케이션에는 적용하기가 불가능하다. 다이내믹 프록시(Dynamic Proxy-JDK1.3)를 이용한 인터셉터 체인(interceptor chain)기술 : JBoss를 비롯한 컨테이너 개발자들을 통해 많이 사용된 방식이다. 하지만 다이내믹 프록시를 이용한 코드는 구현이 매우 복잡하고 특정 구조의 애플리케이션 틀을 따라 작성되어야만 적용 가능하며, 역시 복잡한 프레임워크 내지는 컨테이너의 도움이 필요하다는 면에서 쉽게 일반화되지는 못했다.
6. AspectJ (1) 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발 - Asepct라는 용어와 함께 AOP라는 표현을 처음 사용 자바 VM과 호환되는 최초의 AOP 툴 자바의 언어를 확장한 형태의 구조로 개발 Aspect는 AspectJ의 특별한 컴파일러를 통해 자바 VM에서 사용될 수 있는 코드로 만들어지면서, AOP의 Weaving 작업이 발생함. 위빙 작업을 통해 핵심 관심 모듈의 사이사이에 Aspect형태로 만들어진 횡단 관심(Cross-cutting Concern) 코드들이 삽입되어 애스팩트가 적용된(woven) 최종 바이너리가 만들어 진다. AOP를 이용하면 개발자들은 횡단 관심 모듈을 각각 독립된 모듈로 중복 없이 작성하고 이를 위빙을 통해 핵심 관심 모듈과 결합시키기 때문에 서로 독립성을 모듈을 작성 가능.
6. AspectJ (2) 횡단 관심 모듈을 aspect라는 키워드를 가지는 코드로 작성이 가능 public aspect MethodLoggingAspect { Logger logger = MyLog.getLogger(“methodcall”); pointcut methodcall() : execution (void AccountTransfer.transfer(..)) && !within(MethodLoggingAspect); before() : methodcall() { logger.begin(thisJoinPointStaticPart.getSignature().getName()); } after() : methodcall() { logger.end(thisJoinPointStaticPart.getSignature().getName()); } } 횡단 관심 모듈을 aspect라는 키워드를 가지는 코드로 작성이 가능 MethodLoggingAspect를 작성한 후 AspectJ의 컴파일러를 사용해 컴파일을 하고 AccountTransfer의 transfer() 메쏘드를 실행시키면 메쏘드의 실행 전후에 메쏘드의 시작과 끝을 알리는 로그가 만들어진다. 기존의 코드에 전혀 영향을 주지 않고 자연스럽게 위빙되기 때문에 핵심 관심 모듈을 개발하는 개발자들은 이 부분을 전혀 고려하지 않고 그 모듈 자체의 로직에만 충실히 작성하고 후에 필요한 애스팩트를 만들어 적용할 수 있다.
7. AOP tool 소개 AspectJ는 초기에 제록스 PARC 연구소에서 개발되었다가 2002년에 이클립스 프로젝트에 기증되었고, 현재 IBM의 전폭적인 지원을 받으면서 개발되어 사용되고 있음. BEA가 중심이 되어 개발하고 있는 AspectWerkz는 AspectJ와 달리 자바 언어 자체를 확장하지 않고 기존의 자바 언어만으로 AOP의 사용이 가능하도록 되어 있음. 의존성 삽입(Dependency Injection, 이하 DI) 기반의 프레임워크로 유명한 Spring AOP, JBoss AOP – 인터셉터 체인 방식의 AOP
7. AOP tool 소개 - AspectJ 다른 AOP 툴과는 달리 자바 언어를 확장해서 만들어짐 마치 새로운 AOP 언어를 사용하듯이 aspect라는 키워드를 이용해 애스팩트나 포인트컷, 어드바이스를 만들 수 있다. 일반 자바 컴파일러로는 컴파일이 불가능하고 특별한 AOP 컴파일러를 사용해야 한다. 만들어진 바이너리는 표준 JVM에서 동작 가능한 구조로 되어있기 때문에 특별한 클래스 로더의 지원 없이도 실행 가능하다. AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴. 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기 때문에 가장 이상적인 AOP 툴로 꼽히고 있음. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고 프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. 위빙이 컴파일시에 일어나기 때문에 포인트컷에 의해 선택된 모든 클래스들은 애스팩트가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.
7. AOP tool 소개 - AspectWerkz AspectWerkz는 AspectJ와는 달리 자바 언어를 확장하지 않고 표준 자바 클래스를 이용해서 AOP를 구현. 일반 클래스와 메쏘드를 이용해 쉽게 구현이 가능한 어드바이스와 달리 복잡한 문법이 필요한 포인트컷은 별도의 XML 파일을 이용해 설정할 수 있도록 되어 있다. 자바 클래스와 XML 설정 파일의 접근법에 익숙한 개발자들에게는 매우 편리한 접근 방식. 최근에는 JDK5의 지원에 따라 어노테이션(Annotation)을 이용할 수 있어 더욱 편리해졌음. 위빙은 특별한 클래스 로더를 이용한 로딩타임 바이트코드 생성을 이용한다. AspectJ 못지않은 다양한 조인포인트와 AOP기능을 지원하고 있으며 편리한 개발을 위한 IDE 플러그인이 개발되어 있다.
7. AOP tool 소개 - JBossAOP 프록시를 이용한 인터셉터 체인을 활용해서 위빙을 처리. 필요에 따라서 JavaAssist를 통한 바이트코드 조작을 이용. JBossAOP는 원래 JBoss 서버의 EJB를 위한 인터셉터 체인 기술을 통해 발전해 왔다. JBoss는 최초로 디플로이 시점의 코드 생성이 아닌 인터셉터 체인을 이용한 방식으로 EJB 호출과 그 사이에 필요한 엔터프라이즈 서비스 기능의 삽입을 구현해냈고 이를 발전시켜 왔음. 최근 EJB3나 하이버네이트와 같은 POJO 기반의 엔터프라이즈 개발이 활발해지면서 좀 더 범용적으로 AOP를 사용할 수 있는 형태로 JBossAOP를 개발했다. JBossAOP는 기본적으로 컨테이너에서 동작하지만 컨테이너와 상관없는 독립된 자바 프로그램에서도 사용할 수 있다. AspectWerkz와 마찬가지로 어드바이스는 표준 자바 코드로 작성하고 포인트컷과 다른 설정은 XML 파일이나 JDK5의 어노테이션으로 작성할 수 있다. 아직까지는 JBoss 사용자의 일부에서만 사용되고 있으나 향후 EJB3를 중심으로 한 POJO 기반의 엔터프라이즈 미들웨어 프레임워크가 개발되어짐에 따라 점차 사용률이 올라갈 것으로 기대된다.
7. AOP tool 소개 – SpringAOP (1) SpringAOP는 스프링 프레임워크의 핵심기능 중의 한가지로 스프링의 DI 컨네이너에서 동작하는 엔터프라이즈 서비스에서 주로 사용된다. SpringAOP는 다른 AOP와 달리 기존 클래스의 바이트코드를 수정하지 않고 대신 JDK의 다이내믹 프록시를 사용해서 프록시방식으로 AOP의 기능을 지원하기 때문에 다른 AOP의 기능과 비교해서 매우 제한적인 부분만을 지원한다. 하지만 SpringAOP의 구현 목적은 엔터프라이즈 애플리케이션에서 주로 사용되는 핵심적인 기능에 AOP의 장점을 살려 이를 스프링내에서 사용하는 것이기 때문에 다른 AOP와 같은 AOP의 복잡한 전체 기능을 굳이 다 필요로 하지 않는다. 프록시 기반의 SpringAOP는 Spring IoC/DI와 매우 긴밀하게 연동이 되기 때문에 SpringAOP를 사용하는 방법은 스프링 내에 프록시 빈을 설정해서 쉽게 사용할 수 있다.
7. AOP tool 소개 – SpringAOP (2) JDK의 표준 기능만을 사용하기 때문에 특별한 빌드 과정이 필요없고 클래스 로더를 변경한다거나 하는 번거로운 작업이 없다. 조인포인트의 종류가 메쏘드 기반으로 제한되며 같은 클래스 안의 메쏘드 호출이나 콜백 코드를 사용했을 경우에는 프록시를 적용할 수 없는 단점이 있다. 하지만 대부분의 엔터프라이즈 애플리케이션에서 필요로 하는 주요 AOP 기능들을 메쏘드 호출을 기반으로 충분히 처리가 가능하기 때문에 SpringAOP는 그 제한된 AOP 기능에도 불구하고 현장에서 가장 빠른 속도로 적용되어 사용되는 AOP 솔루션 중의 하나임. SpringAOP는 어드바이스와 포인트컷을 모두 표준 자바 클래스로 작성할 수 있다. 필요에 따라서 포인트컷은 설정 파일 내에서 포인트컷 팩토리 빈을 이용해서 정규식으로 표현이 가능하다. SpringAOP의 최대 단점은 복잡한 프록시 설정 구조로 Spring빈을 정의한 파일에서 프록시를 정의한 부분의 다른 XML기반의 AOP에 비해서도 복잡한 편인데 이 경우 SpringAOP가 지원하는 AutoProxyingCreatorBean 등을 이용하면 설정 코드를 매우 단순하게 작성하는 것이 가능하다.
8. AOP 향후 과제 (1) 표준의 부재 - AOP는 현재 정해진 표준이 없으며 표준을 정할 기구나 조직 없음 - AOSD (International Conference on Aspect Oriented Software Development)와 같은 행사들이 꾸준히 열리면서 AOP 연구자들과 툴 개발팀, 개발자들 사이에 많은 의견을 모으고 표준을 위한 노력이 시작되었음 - 최근 AOP툴 업체들 간에 협력이나 통합 구조가 가시적으로 보이고 있다. ( 대표적인 AOP 툴인 AspectJ와 AspectWerkz가 협력해서 통합된 AOP 툴을 만들기로 하고 지금 작업이 진행중 )
8. AOP 향후 과제 (2) 학습의 어려움 - AOP를 접해온 개발자들의 가장 큰 AOP에 대한 비판은 AOP가 너무 어렵다는 것이다. - AOP를 배우는 것은 기존 OOP에 대한 완벽한 지식을 바탕으로 한다고 해도 사실 상당한 발상의 전환이 필요하고 그 개념이 난해한 부분이 많음. - 새로운 용어들에 익숙해지고 그 의미를 정확히 파악 필요. - 기존 애플리케이션에 어떻게 적용해야할지 그 적용 방법과 아이디어를 내는 것도 수월하지 않음. - 충분히 AOP 기술과 개념에 익숙해져야 할 시간이 필요할 것이고, 또 AOP 기반의 애플리케이션을 설계하고 구현하는데 필요한 다양한 방법론과 설계 기술들에 대한 연구 필요. - AOP로 만든 프로그램은 프로그램의 흐름을 이해하고 추적하기가 매우 힘들수도 있지만 독립된 관점에 따라서 애플리케이션을 살펴보고 이를 통합해서 생각하는 훈련만 된다면 이전에 많은 다른 차원의 코드들이 섞여있던 때에 비해 애플리케이션에 대한 이해는 훨씬 수월해질 것이라고 기대된다.
8. AOP 향후 과제 (3) OOP와의 충돌 - Cross-cutting concern의 구현을 위해 기존 클래스(객체)의 내부에 직접적인 영향을 줄 수 있기 때문에 OOP의 캡슐화를 깨뜨린다. - AOP의 도움 없이 객체지향적인 방법으로 Cross-cutting concern 부분에 대한 해결책을 제시할 수 있는가? - 핵심 디자인을 거의 손대지 않고도 시스템 전반에 영향을 주는 횡단 관심 모듈을 독립성 있게 개발하고 전 시스템에 걸쳐 자유롭게 삽입, 제거가 가능해지기 때문에 초기 S/W 디자인에 큰 도움을 준다. - AOP 만능주의자가 되어 OOP적인 바른 접근과 설계를 뒷전으로 하는 것은 진정한 AOP가 아니다. - AOP는 이미 잘 설계되어 있는 디자인을 더욱 쉬운 방법으로 적용할수 있게 만들어 줄 뿐이지 AOP를 쓴다고 해서 기존의 OOP적인 설계와 접근방법을 포기하거나 가볍게 여겨서는 안된다.
9. AOP의 미래 AOP는 갑자기 어디서 떨어진 마법의 도구가 아니라 현장에서 개발에 매진하는 개발자들이 스스로 기존 기술과 방법의 문제점을 극복하기 위해 찾아낸 개발자를 위한 도구이다. 모든 소프트웨어 기술이 다 그렇듯이 AOP도 결국 좀 더 효과적인 방법으로 더 나은 품질의 제품을 개발하는데 그 존재 가치가 있다. 최근에 불고 있는 POJO 기반의 개발 기술의 열풍은 이러한 근본적인 문제에 대한 개발자 스스로의 반성이 현실로 나타난 것이다. 아드리안 콜리어는 POJO 기반의 애플리케이션 개발의 3대 기술을 AOP, DI, 어노테이션(Annotation)이라고 하고 이 3가지가 앞으로의 시대를 주도하는 핵심 개발 기술이 될 것이라고 이야기한다. 이미 어노테이션은 자바 5의 표준 기술로 자리를 잡았고 의존 삽입 또한 다양한 프레임워크의 지원 하에 매우 빠른 속도로 사실상의 표준 기술로 자리 잡고 있다.
10. 용어 정리 (1) 조인포인트 (JoinPoint) 횡단 관심 모듈의 기능이 삽입되어 동작할 수 있는 실행 가능한 특정위치를 말한다. 예를 들어 메쏘드가 호출되는 부분 또는 리턴되는 시점이 하나의 조인포인트가 될 수 있다. 또 필드를 액세스하는 부분, 인스턴스가 만들어지는 지점, 예외가 던져지는 시점, 예외 핸들러가 동작하는 위치, 클래스가 초기화되는 곳 등이 대표적인 조인포인트가 될 수 있다. 각각의 조인포인트들은 그 안에 횡단 관심의 기능이 AOP에 의해 자동으로 추가되어져서 동작할 수 있는 후보지가 된다. 포인트컷 (PointCut) 포인트컷(pointcut)은 어떤 클래스의 어느 조인포인트를 사용할 것인지를 결정하는 선택 기능을 말한다. AOP가 항상 모든 모듈의 모든 조인포인트를 사용할 것이 아니기 때문에 필요에 따라 사용해야 할 모듈의 특정 조인포인트를 지정할 필요가 있다. 일종의 조인포인트 선정 룰과 같은 개념이다. AOP에서는 포인트컷을 수행할 수 있는 다양한 접근 방법을 제공한다. 어드바이스 또는 인터셉터 (Advice or Intercepter) 어드바이스(advice)는 각 조인포인트에 삽입되어져 동작할 수 있는 코드를 말한다. 주로 메쏘드 단위로 구성된 어드바이스는 포인트컷에 의해 결정된 모듈의 조인포인트에서 호출되어 사용된다. 일반적으로 독립적인 클래스 등으로 구현된 횡단 관심 모듈을 조인포인트의 정보를 참조해서 이용하는 방식으로 작성된다. 인터셉터(intercepter)는 인터셉터 체인 방식의 AOP 툴에서 사용하는 용어로 주로 한 개의 invoke 메쏘드를 가지는 어드바이스를 말한다.
10. 용어 정리 (2) 위빙 또는 크로스컷팅 (Weaving or Cross-cutting) 포인트컷에 의해서 결정된 조인포인트에 지정된 어드바이스를 삽입하는 과정이 위빙이다. 위빙은 AOP가 기존의 핵심 관심 모듈의 코드에 전혀 영향을 주지 않으면서 필요한 횡단 관심 기능을 추가할 수 있게 해주는 핵심적인 처리과정이다. 다른 말로 크로스컷팅(crosscutting)이라고 하기도 한다. 위빙을 처리하는 방법은 후처리기를 통한 코드생성 기술을 통한 방법부터 특별한 컴파일러 사용하는 것, 이미 생성된 클래스의 정적인 바이트코드의 변환 또는 실행 중 클래스로더를 통한 실시간 바이트코드 변환 그리고 다이내믹 프록시를 통한 방법까지 매우 다양하다. 인트로덕션 또는 인터타입 선언 인트로덕션(Introduction)은 정적인 방식의 AOP 기술이다. 동적인 AOP 방식을 사용하면 코드의 조인포인트에 어드바이스를 적용해서 핵심관심 코드의 동작 방식을 변경할 수 있다. 인트로덕션은 이에 반해서 기존의 클래스와 인터페이스에 필요한 메쏘드나 필드를 추가해서 사용할 수 있게 해주는 방법이다. OOP에서 말하는 오브젝트의 상속이나 확장과는 다른 방식으로 어드바이스 또는 애스팩트를 이용해서 기존 클래스에 없는 인터페이스 등을 다이내믹하게 구현해 줄 수 있다. 애스팩트 또는 어드바이저 (Aspect or Advisor) 애스팩트(aspect)는 포인트컷(어디에서)과 어드바이스(무엇을 할 것인지)를 합쳐놓은 것을 말한다. 필요에 따라서 인트로덕션도 포함할 수 있다. AspectJ와 같은 자바 언어를 확장한 AOP에서는 마치 자바의 클래스처럼 애스팩트를 코드로 작성할 수 있다. AOP 툴의 종류에 따라서 어드바이스와 포인트컷을 각각 일반 자바 클래스로 작성하고 이를 결합한 어드바이저 클래스를 만들어서 사용하는 방법도 있다.
11. 토론 주제 AOP는 Cross-Cutting Concern 주제를 다루기에 적합한 기술인가? AOP가 등장하게 된 배경과 OOP와의 관계는 어떠한가? AOP가 가지는 개념은 무엇인가? AOP에서 새롭게 등장한 용어들은 무엇을 의미하는가? AOP를 적용할 경우 프로젝트에 어떤 효과를 줄 수 있는가? AOP를 프로젝트에 적용할 경우 고려해야 할 사항은 무엇인가?
12. 정리 1. SpringAOP, AspectJ의 기술적인 부분만을 볼 것이 아니라 AOP에 대한 개념적인 부분을 이해하는데 더 많은 시간을 할애 -> AOP는 새로운 관점의 기술(방법)이면서 동시에 앞으로 계속 변화, 발전해 갈 수 있으므로 AOP에 대한 등장 배경 및 기본 개념에 충실할 필요 있음. 2. Aspect의 적용은 어플리케이션 실행 Performance 저하를 가져 오므로 꼭 필요한 곳에 제한된 범위를 두고서 사용하는것이 바람직함.