Programming/Spring

Spring AOP - XML 기반으로 구현

byeong07 2018. 6. 13. 17:40

- AOP(Aspect Orieted Programming) : 관점 지향 프로그래밍

 

프로그래밍을 하다보면 공통적인 기능이 많이 발생합니다.

 

이러한 공통 기능은 상속을 통해서 모든 모듈에 적용을 할 수 있지만 몇 가지 문제가 있습니다.

 

먼저 Java에서는 다중 상속이 가능하지 않기 때문에 한계가 있으며, 기능을 구현하는 부분에

 

핵심 기능 코드와 공통 기능 코드가 섞여 있어서 효율이 떨어지게 됩니다.

 

이러한 문제점 때문에 핵심 기능과 공통 기능을 분리하며, 공통 기능을 필요로 하는 핵심 기능들에서 사용하는 방식의

 

AOP가 등장을 하게 되었습니다.

 

- AOP 관련 용어

 

* Aspect : 공통 기능

 

* Advice : Aspect의 기능 자체

 

Aspect를 공통 기능이라 크게 묶었으면 Advice는 그 안의 세부적인 주요 기능이라 생각하면 됩니다.

 

* Joinpoint : Advice를 적용해야 되는 부분(ex. 필드, 메소드 - Spring에서는 메소드만 해당)

 

아래 그림을 보시면 핵심 기능들이 있는데 핵심 기능 각각을 Joinpoint라 생각하면 됩니다.

 

* Pointcut : Joinpoint의 부분이며 실제로 Advice가 적용된 부분

 

* Weaving : Advice를 핵심 기능에 적용하는 행위

 

Spring에서 AOP 구현은 Proxy를 사용합니다.

 

예를 들어 공통 기능을 핵심 기능이 시작하기 전과 끝난 후에 사용을 하겠다고 설정을 했을 때 순서입니다.

 

공통 기능과 핵심 기능이 직접적으로 접촉하는 것이 아니라 Proxy를 통해서 수행을 합니다.

 

AOP를 구현하는 방법은

 

- XML 스키마 기반으로 구현

 

- @Aspect 어노테이션 기반으로 구현

 

이렇게 두 가지가 있는데 먼저 XML 스키마를 이용해서 구현하겠습니다.

 

 

1. XML 기반의 AOP 구현

 

먼저 고양이의 정보를 출력하는 클래스를 생성한 후에 AOP를 적용하겠습니다.

 

 

고양이의 나이, 이름, 색깔을 담을 변수와 setter(), getter()를 생성하고, 고양이의 정보를 출력할 getCatsInfo() 메서드를

 

생성했습니다.

 

applicationContext.xml에서 bean을 생성합니다.

 

aopEx/src/main/resources/applicaitonContext.xml

 

 

생성한 bean을 가져와서 정보를 출력할 MainClass를 생성 후 작성합니다.

 

aopEx/src/main/java/com/aopEx/MainClass.java

 

 

 

MainClass를 실행하면 고양이의 정보가 출력됩니다.

 

여기에 AOP를 적용하겠습니다.

 

1) pom.xml 파일에 의존 설정

 

 

pom.xml에 작성하면 관련 라이브러리가 다운로드됩니다.

 

 

2) 공통 기능의 클래스 제작(Advice 역할 클래스)

 

aopEx/src/main/java/com/aopEx/LogAop.java

 

 

loggerAop() 메서드에서 핵심 기능인 joinpoint를 매개 변수로 받습니다.

 

그리고 받아온 핵심 기능(메서드명)이 무엇인지 출력하기 위해서 getSignature() 메서드를 사용해서

 

signatureStr에 담아줬습니다.

 

공통 기능은 시간을 출력하도록 구현했고, 아래에 joinpoint.proceed() 메서드를 사용해서 핵심 기능을 실행한 후에

 

finally 부분에서 공통 기능인 시간을 더 출력을 합니다.

 

이 클래스는 위에서 설명을 드린 proxy라 생각하면 됩니다.

 

 

3) XML 설정 파일에 Aspect

 

aopEx/src/main/resources/applicationContext.xml 파일의 Namespaces에서 aop를 선택합니다.

 

 

선택 후 Source를 보시면 윗 부분에 aop 태그를 사용할 수 있도록 되어 있는 것을 확인할 수 있습니다.

 

 

위에 공통 기능을 할 loggerAop() 메서드를 사용하기 위해서 bean으로 만들어주고, aop를 설정합니다.

 

 

AOP 설정은 이렇게 하면 됩니다.

 

MainClass에서 실행하면 AOP가 적용이 되었습니다.

 

LogAop 클래스에서 설정한 것처럼 핵심 기능 시작 전 실행될 공통 기능이 실행되고,

 

위에서 작성했던 핵심 기능(고양이의 정보 출력)이 실행, 그 뒤에 핵심 기능 후에 실행될 공통 기능이 실행되었습니다.

 

실제 핵심 기능에는 공통 기능을 추가하지 않고, 따로 클래스를 작성한 후

 

xml에 파일로 어떤 공통 기능을 어떤 범위에서 사용을 할 것인지 설정을 했습니다.

 

이렇게 aop를 적용해서 사용하면 소스 코드가 간결해지고, 나중에 유지보수를 하기 편합니다.

 

참고 - advice 종류

 

<aop:before> : 메서드 실행 전에 advice 실행

 

<aop:after-returning> : 정상적으로 메서드 실행 후에 advice 실행

 

<aop:after-throwing> : 메서드 실행 중 exception 발생 시 advice 실행

 

<aop:after> : 메서드 실행 중 exception이 발생하여도 advice 실행

 

<aop:around> : 메서드 실행 전/후 밑 exception 발생 시 advice 실행

 

보통 around나 before를 많이 사용합니다.