Spring에서 사용되는 관점지향 프로그래밍에 대해 알아보자.


◆ 관점 지향 프로그래밍
AOP (AspectOrientedProgramming)

객체 단위로 모듈화 시키는 OOP와는 달리 AOP는 관점 별로 모듈화 시키는 개념의 프로그래밍이다.
여러 곳에서 일어나는 공통적인 작업( cross-cutting concern : Aspect )들을 따로 분리해서 설계하고, 이것을 조합시키는 방식


▶ 작동 형태

 자동 호출시킬 메서드를 등록 시켜놓고 해당 메서드의 호출 타이밍(관점)을 결정하는 객체 또는 객체의 메서드패턴등을 같이 등록시켜 놓게되면, 직접적으로 호출시키지 않아도 등록된 타이밍(관점)에 따라 자동적으로 호출된다.
따라서 공통적으로 처리해야할 메서드들을 등록시켜 놓고 때에 따라 자동 호출 시키는 형태로 사용하는 것을 관점 지향 프로그래밍이라 한다.


▶ 설정

  • Aspectj weaver 라이브러리 메이븐 추가
    AOP를 하기 위해서는 Aspectj weaver라이브러리가 필요하다.
    http://mvnrepository.com/artifact/org.aspectj/aspectjweaver 에서 메이븐 설정코드를 가져올 수 있다.
  • spring bean cofiguration File설정
    AOP설정 또한 spring bean configuration File에서 한다.
    aop를 사용하기 위해선 해당 파일의 Namespaces탭에서 aop를 체크해야 사용할 수 있으므로, aop를 체크해 주도록 하자.


◆ 자동 호출 메서드 등록

▶ 등록 방법

1. IOC컨테이너에 공통작업 메서드를 가지고 있는 객체를 등록시켜 둔다.

<bean id="sa" class="aop.alpha.SampleAspect" /> 

SampleAspect객체에 공통작업을 자동으로 호출시킬 메서드를 가지고 있는 경우


2. <aop: .. > 태그들을 이용하여 호출할 메서드를 등록한다.

<aop:config>
    <aop:aspect ref="sa">
        <aop:after method="work" pointcut="execution( boolean *(..) )" />
    </aop:aspect>
</aop:config>
  • <aop:config>

    : aop설정태그, 모든 aop설정을 해당 태그 안에서 한다.

  • <aop:aspect ref="">

    : 자동호출 시킬 공통작업 메서드를 가지고 있는 객체의 id를 ref로 연결시켜준다.

  • <aop:after>

    : 공통작업 메서드의 호출 순서를 결정하는 태그로, 여러 종류가 있다.

  • method

    : 공통작업 메서드 이름

  • pointcut

    : 공통메서드의 호출 시기를 결정


3. 자동호출 메서드가 호출될 객체 등록

별 다른 작업 없이 객체를 등록한다. 자동 호출 메서드의 호출을 결정하는 것은 pointcut이다.

특정 클래스에 자동호출이 따라오는 메서드를 포함하고 있다면, 왼쪽에 화살표 모양이 표시되기 때문에 확인이 가능하다. ( 안나오는 버전도 있음 )


※ Ex

// 1. 공통작업 메서드를 가지고 있는 객체등록 (SampleAspect)
<bean id="sa" class="SampleAspect" />
// 2. 공통작업을 언제 어떤순서로 호출시킬  설정
<aop:config>
	<aop:aspect ref="sa">
		<aop:after method="work" pointcut="bean(ac)" />
    </aop:aspect>
</aop:config>
// 3. 공통작업이 호출될 객체를 등록
<bean id="ac" class="AutoCall" />

위 처럼 등록할 경우 AutoCall객체의 메서드가 호출된 후 자동으로 SampleAspect객체의 work()메서드가 호출된다.


◆ 자동호출 메서드의 호출 시기 결정 태그

위의 예제에서 사용한 <aop:after>은 메서드가 호출된 후에 자동 호출 메서드를 호출 시키는 태그이다.
호출 시기를 결정하는 태그의 종류로는 아래 5가지 종류가 있다.


▶ <aop:after>

(pointcut과 일치하는)메서드가 호출되고 난 후에 오류와 상관없이 무조건 호출

▶ <aop:before>

메서드가 호출되기 전 오류와 상관없이 무조건 호출

▶ <aop:after-throwing>

메서드에서 에러가 터질 때 만

▶ <aop:after-returning>

메서드가 정상적으로 끝난 경우에만

▶ <aop:around>

after와 befor에 모두 호출, around의 경우에는 작동 형태나 설정방법 등이 조금 다르다.


◆ pointcut

pointcut은 자동호출 메서드를 호출 시킬 메서드패턴 또는 객체를 결정하는 옵션이며, 세 가지의 키워드를 가지고 설정할 수 있다.

  • 또한, pointcut과 일치하는 메서드를 가지고 있는 객체들은 IOC컨테이너 왼쪽에 화살표표시가 나타나게 된다.


▶ 키워드에 따른 설정 방법

pointcut에서 사용할 수 있는 키워드는 총 3가지가 있다.


1. bean

스프링이 관리하는 특정 빈(id)의 모든 메서드, 즉 IOC컨테이너의 등록된 객체의 id로 설정하여 해당 객체의 모든 메서드를 pointcut으로 설정하는 방법이다.

<bean id=target class=data.Target/>
<aop:after ... pointcut="bean(target)" />

=> 또는 bean(t*) 로 설정하게 되면 t로 시작하는 모든 id객체들이다.


2. within

특정 패키지 소속의 모든 객체 또는 메서드

pointcut = "within( java.util.* )"


3. execution

 특정 패턴과 일치하는 메서드를 pointcut으로 등록 시키는 키워드로, 아래 기호와 함께 사용할 수 있다.

  •  * 없으면 안 되지만, 있으면 모든 것을 의미
  • .

    하나가 있거나 없거나를 의미

  • ..

    하나 또는 여러 개가 있거나 없거나

  • ex ) pointcut = “execution( boolean add*( .. ) )”
    boolean형을 반환하는 메서드명이 add로 시작하는 인자가 있거나 없는 모든 메서드

※ 파라미터로 타입/이름을 직접적으로 적어줘도 된다. 단 매개변수 타입을 지정할 때는 호출되는 메서드에서 받는 인자와 동일한 형태를 적어주어야 한다.

※ Object형을 인자로하는 메서드의 경우에는 String도 받을 수 있지만 pointcut에서는 Object라고 적어야만 인식된다.

※ aop 자동호출 메서드를 등록할 수 있는 메서드들은 IOC컨테이너에 등록된 객체들의 메서드만 등록이 가능하고, 직접 new를 통해서 만들 객체는 해당사항이 아니다.


▶ pointcut을 따로 정의해놓고 쓸 수도 있다.

<aop:pointcut>태그를 이용하여 pointcut을 id로 등록 후 pointcut-ref옵션으로 id를 주는 형식

 
<aop:config>
    <aop:pointcut expression="bean(target)" id="p1" />
    <aop:pointcut expression="within(java.util.*)" id="p2" />
    <aop:aspect ref="sa">
        <aop:after-returning method="work" pointcut-ref="p1" />
        <aop:after-returning method="work" pointcut-ref="p2" />
    </aop:aspect>
</aop:config>
  • expression : pointcut설정형태
  • id : pointcut-ref로 설정할 id


▶ 여러 개의 pointcut을 and나 or을 통해 동시에 등록 가능

and는 두개의 조건을 동시에 만족해야하고, or은 둘 중 하나
ex ) <aop:pointcut expression=”within(java.util.) and execution( contains*(..))”/>