어플리케이션의 공통기능들을 핵심로직과 분리하여 공통관심(로깅, 트랜잭션 등등)으로 두고 관리한다. 
이떄 기본적이 개념은 공통 관심 사항을 구현한 코드를 핵심 로직을 구현한 코드 안에 삽입하는 것이다. 

 트랜잭션 같은 부가기능은 핵심기능과 같은 방식으로 모듈화하기 매우 힘들다. 이름 그대로 부가기능이기때문에 스스로 독립적인 방식으로 존재해서는 적용되기 어렵기 떄문이다. 그래서 데코레이션 패턴, 다이내믹 프록시, 오브젝트 생성 후처리, 자동 프록시 생성, 포인트 컷과 같은 기법이 생겨났다.
  그리고 이런 독립적으로 모듈화가 불가능한 것들의 모듈화를 연구해온 사람들이 기존의 객체지향 설계 페러다임과 구분되는 새로운 특성이 있다고 생각했고 그것을 애스팩트라고 불렀다. 
 
 애스팩트 : 그 자체로 애플리케이션의 핵심 기능을 담고 있진 않지만 애플리케이션을 구성하는 한가지 요소이고 핵심기능에 부가되어 의미를 갖는 특별한 모듈 
 그리고 이 모듈을 만들어 설계하고 개발하는 방법을 애스팩트 지향 프로그래밍(AOP)이라고 한다.

target : 부가기능을 부여할 대상
advice : 타깃에게 제공할 부가기능을 담은 모듈 , 오브젝트, 메소드 레벨 모두 정의가능하다.
weaving : advice를 핵심기능에 적용하는 것
aspect : 여러 객체에 공통으로 적용되는 기능
joinpoint : advice를 적용 될수있는 위치, 타깃 오브젝트가 구현한 인터페이스는 모두이다. 
pointcut: joinpoint의 부분집합으로서 실제로 advice가 적용되는 joinpoint를 나타낸다. 
proxy :  클라이언트와 타킷 사이에 투명하게 존재하면서 부가기능을 제공하는 오브젝트 DI를 통해 타깃대신 클라이언트에 주입된다.
advisor : 포인트컷과 어드바이스를 하나씩 갖고 있는 오브젝트. 부가기능(어드바이스)를 어디에(포인트컷) 전달할것인가 아는 기본모듈
            스프링만의 용어임

세가지 weaving방식 
-컴파일시 : aspectJ에서 사용 컴파일 결과 aop가 적용된 클래스 파일이 생성된다. 
-클래스 로딩시 : 원본 클래스 파일을 변경하지 않고 클래스를 로딩할때 jvm이 변경된 바이트 코드를 사용하도록 함으로써 aop를 적용한다. aspectJ도 지원함
-런타임시 : 소스 코드나 클래스 정보 자체를 변경하지 않는다 대신 프록시를 사용한다. 

1.스프링의 AOP( 프록시를 이용한 AOP )
모듈화가 된 부가기능(advice)과 적용대상(pointcut)의 조합을 통해 여러 오브젝트에 산재해서 나타는 공통적인 기능을 손쉽게 개발하고 관리할수 있는 기술이다. 
 스프링은 다이내믹 프록시 기술을 이용해 AOP개발 기능을 제공한다. 
프록시 기술 방식의 AOP는 데코레이션 패턴 또는 프록시 패턴을 응용해 기존 코드에 영향을 주지 않은 채로 부가기능을 타깃오브젝트에 제공할수있는 객체지향 프로그래밍 모델로부터 출발한다. 여기에 포인트 컷이라는 적용 대상 기법과 자동 프록시 생성이라는 적용 기법까지 적목하면 비로소  AOP라고 부를수있는 효과적인 부가기능 모듈화가 가능해진다. 

client가 target을 직접적으로 알고 있으면 안된다. client가 사용할 오브젝트를 DI컨테이너 설정을 통해 바꿀수없기 때문이다. 따라서 DI원리에 의존하고 있는 데코레이션 패턴이 적용된 프록시 방식이 적용되지 못한다. 
 따라서 Client가 target이 구현하고있는 인터페이스를 이용해 의존하도록 만들어야 한다.  aop는 하나의 모듈을 많은 오브젝트의 메소드 실행시점에 일괄 적용할 수 있어야 한다.  그래서 스프링은 자동 프록시 생성기를 이용해서 컨테이너 초기화중에 만들어진 빈을 바꿔치기해 프록시 빈을 자동으로 등록해준다. 빈을 등록하는 로직은 포인트컷을 이용하면되고 어노테이션,xml을 통해 이미 정의된 빈의 의존관계를 바꿔치기하는것은 빈 후처리가 사용한다.  이 자동 프록시 생성기가 바로 스프링의 프록시 기반 AOP의 핵심동작원리이다. 

 최소한 네가지 빈을 등록해야한다.
 -자동 프록시 생성기
스프링의 DefaultAdvisorAutoProxyCreator 클래스를 빈으로 등록한다. 다른 빈을 DI하지 않고 자신도 DI되지 않으며 독립적으로 존재한다. 애플리케이션 컨텍스트가 빈 오브젝르를 생성하는 과정에 빈 후처리기로 참여한다. 빈으로 등록된 어드바이저를 이용해서 프록시를 자동으로 생성하는 기능을 한다.

 -어드바이스 
 부가기능을 구현한 클래스를 빈으로 등록한다. 

 -포인트컷 
 스프링의 AspectJExpressionPointcut을 빈으로 등록하고 expression프로퍼티에 포인트컷 표현식을 넣어주며 된다 
 
 -어드바이져
 자동프록시 생성기에 의해 자동 검색되어 사용된다. 

<aop:config>
    <aop:pointcut id="mybatis_operations"   expression="execution( *com. *Dao.)"/>
    <aop:advisor advice-ref="mybatis_txAdvice" pointcut-ref="mybatis_operations"/>
</aop:config>

<aop:config> : AspectJAdvisorAutoProxyCreator 을 빈으로 등록한다.
<aop:pointcut> : AspectJExpressionPointcut을 빈으로 등록한다.
<aop:advisor> :  advice와 pointcut의 ref를 프로퍼티로 갖는 DefaultBeanFactoryPointcutAdvisor를 등록한다.

1.AOP 인터페이스 구현과 <bean> 등록을 이용하는 방법
2.AOP 인터페이스 구현과 aop 네임스페이스의 <aop:advisor>를 이용 하는 방법
3.임의의 자바 클래스와 aop 네임스페이스의 <aop:aspect>를 이용하는 방법
2번과 마찬가지로 aop네임페이스를 사용하나 어드바이저 대신 에스펙트라는 개념을 이용한다. 
스프링 aop를 사용한다면 어떤 개발 방식이든 모두 프록시 방식의 AOP다. 

스프링의 aop는 기본적으로 다이내믹 프록시를 기법을 사용한다. 이 기법을 사용하려면 기본적으로 인터페이스가 있어야 하는데 특별히 레거시 클래스코드를 써야하는 경우 어떻게 해야할까
이때는 클래스 프록시 모드를 사용한다. 인터페이스가 아닌 레거시 클래스 코드일경우 JDK 다이내믹 믹 프록시가 아닌 CGLIB 라이브러리가 제공된다. 
 <tx: config proxy-target-class="true">
클래스 프록시는 타깃클래스를 상속해서 프록시를 만드므로 final클래스는 적용할수없으며 생성자가 두번호출되는 문제로 생성자에서 중요한 작업은 피하도록 해야한다. 그리고 클래스의 public 메소드 전체가 트랜잭션의 대상이 된다. 

4.@AspectJ 애노테이션을 이용한 애스펙트 개발 방법
<aop:config> 대신 <aop:aspectj-autoproxy /> 사용하여 @AspectJ가 붙은 것을 모두 에스펙트로 등록해줘야 한다. 어드바이스와 포인트컷은 자바 클래스내에 정의한 어노테이션을 이용해 정의된다.
 -@PointCut 
 -어드바이스: @Before, @AfterReturning,@AfterThrowing,@After,@Around
 

2.AspectJ AOP ( 바이트코드 새성과 조작을 통한 AOP )
 자바 언어 자체를 확장해서 만든 aspect문법을 이용해 에스펙트를 작성해야한다.  스프링의 AOP는 단지 DI의 도움을 받아 프록시 오브젝트를 추가함으로써 애스펙트를 적용할수있다. 하지만 AspectJ는 이와 달리 아예 타깃오브젝트 자체의 코드를 바꿈으로서 애스펙트를 적용한다.  따라서 프록시를 사용하지 않는다. 대신 타깃 오버젝트와 자바 코드에 처음부터 애스펙트가 적용되어 있던것처럼 클래스 바이트코드를 변경하는 작업이 필요하다. 
 자바의 프록시 기법으로는 특정 오브젝트가 생성된 시점이나 특정 필드를 읽을 지점에 어드바이스를 추가할 방법이 없다. 하지만 AspectJ는 private 메소다의 호출, 스태틱 메소드 호출, 오브젝트의 생성순간 까지 다 참여가능하다. 
 
스프링 빈에서 작업의 실행을 어드바이즈하는것이 전부라면 스프링 AOP가 좋은 선택이나 컨테이너가 관리하지않는 객체(도메인 등)를 어드바이즈하거나 간단한 메서드들 외에 조인포인트를 어드바이즈해야된다면 AspectJ 를 사용하는것이 좋다. 

출처 :토비,  4.0 최범균저

'STUDY > SPRING' 카테고리의 다른 글

Java EE 디자인패턴(ing)  (0) 2018.11.12
DATA Access  (0) 2018.11.08
TRANSACTION  (0) 2018.11.06
MVC  (0) 2018.11.02
[코드로 배우는 스프링 웹프로젝트]  (0) 2018.10.31

+ Recent posts