Spring AOP Aspect Oriented Programming
• 여러 객체에 공통적으로 적용할 수 있는 기능을 분리해서 재사용성을 높여 핵심기능 구현을 분리함으로써 핵심기능 구현 코드 수정없이 공통기능을 적용할 수 있게 만들어줌
💡
∙ 관점지향 : AOP
문제를 바라보는 관점을 기준으로 프로그래밍을 하는 기법을 말함
∙ 횡단관점 (관심사) 분리 : 프로젝트 개발시 어떤 관점에서 분리시킬지 연구하는것
핵심 비지니스 로직과 구분하기 위해 공통기능을 횡단관점/횡단관심사(cross-cutting concern) 이라고 한다
proxy 프록시
• 핵심 기능의 실행은 다른객체에 위임하고 부가적인 기능을 제공하는 객체를 말함
• 핵식기능 구현대신 여러 객체에 공통적으로 적용할 수 있는 (부가)기능 구현
• 스프링도 프록시를 이용해서 AOP를 구현하고 있다.
💡
OOP : 업무들을 하나의 클래스 단위로 모아 모듈로 분리시켜 재활용성과 보수성을 높일 수 있다.
AOP : 모듈들에서 관심사에 부합되는 것이 존재하는지 존재하면 동작되게 준비시켜두는 개념
용어
Joinpoint : 클래스의 인스턴스 생성시점, 메소드 호출시점 및 여러 어플리메이션을 실행할때 "특정 작업이 시작되는 시점" Advice를 적용가능한 지점
Advice : Joinpoint에 삽입 되어져 동작할 수 있는 코드로 "언제" 공통관심기능을 핵심 로직에 적용할지를 정의하고 있다.
Joinpoint(메소드 호출) 실행되는 전/후 시점(5가지)에 Adivce로 필요한 기능을 실행시키는것
Pointcut : 실제 관점, 발생하는 상황
Advisor : Advice와 Pointcut을 하나로 묶어서 말함 (개념)
Weaving : Advice를 ㅎ개심로직 코드에 적용하는 것을 말함 (개념)
Target : JoinPoint가 발생되는 대상 (개념)
Aspect : 공통관점 사항, 여러 객체에 공통으로 적용되는 기능을 말함 (개념)
Advice weaving 3가지 방식
☑ 컴파일시 weaving : AspectJ 사용방식
☑ 클래스 로딩 weaving : AspectJ 지원
☑ 런타임시 weaving : 프록시 이용
스프링 AOP
• 자체적으로 프록시 기반의 AOP를 지원하고 있으나 메소드 호출만 지원 다양한 Jointpoint를 지원하는 AspectJ 많이 사용
✔ 스프링 AOP구현 방법 3가지
☑ XML 스키마 기반의 POJO 클래스 이용한 AOP 구현
☑ AspectJ에서 정의한 @Aspect 어노테이션 기반의 AOP 구현
☑ 스프링 API를 이용한 AOP 구현
진행과정

스프링은 프록시를 이용함
스프링은 Aspect의 적용대상(target)이 되는 객체에 대한 프록시를 만들어 제공, 프록시를 통해 대상객체에 간접적으로 접근하는 방식으로 돌아감. 프록시 객체 생성은 대상객체의 인터페이스 유무에 따라 생성되며 인터체이스가 없으면 생성 안된다.
즉, 인터페이스를 기반으로 프록시 객체를 생성하기 때문에 인터페이스에 정의되어 있지 않은 메소드는 AOP가 적용되지 않는다.
Advice
• 프록시로 메소드 호출시, Adpect를 적용하기 때문에 구현 가능한 Advice의 종류는 5가지
∙ Before : 타겟 메소드 동작 전 실행
∙ AfterReturning : 타겟 메소드 정상 종류 후 실행
∙ AfterThrowing : 타겟 메소드 동작중 예외 발생시 실행
∙ After : 타겟 메소드 종류후 실행
∙ Around : 타겟 메소드 동작 전 후 또는 예외발생시점에 실행(Before + After) 📌
가던길 갈 수 있게 해주는 메소드가 존재함
PreceedingJoinPoint의 proceed()로 공통기능 처리후 가던길 가라 해주면 됨
AOP 설정
1. 라이브러리 추가
∙ aspectj weaver
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
∙ spring-aop (spring context 배치시 자동 배치됨)
2. AOP세팅을 위한 컨트롤러 별도로 생성
∙ aop-context.xml (스키마 추가)
∙ web.xml 설정파일 추가
3. XML 기반 AOP
과정
1 - 공통 기능을 제공할 클래스 만들기
2 - xml 파일에 aspect, pointcut, advice(before, around) 골라 설정
1) 공통기능 제공할 클래스
spring.aop.advice 패키지 > Advice class
2) xml aop 설정
☑ aop 태그
| <aop:config> | aop 설정 지정하는 태그 |
| <aop:pointcut> | Aspect 설정 태그 |
| <aop:pointcut> | Pointcut 설정 태그 |
| <aop:around> | Around advice 추가, 나머지 4개도 : before :after ... |
☑ 구조①
<aop:config>
<aop:aspect id="관점이름" ref="공통기능 제공 클래스의 빈태그 id값">
<aop:pointcout id="포인트컷 이름" expression="표현식으로 발생상황 기술" />
<aop:around pointcut-ref="적용할 포인트컷 id" method="공통기능 수행할 메소드명" />
</aop:aspect>
</aop:config>
☑ 구조②
<aop:config>
<aop:pointcout id...
<aop:pointcout id...
...
<aop:aspect id..
<aop:before
<aop:after
<aop:around
</aop:aspect>
</aop:config>
👀 AOP 설정
expression : execution (핵심기능의 메소드명을 범용적으로 필터링되게 작성)
* : 모든 접근 지정자 패키지 클래스명 상관없고
main* : main으로 시작하는 메소드명
(..) : 메소드 매개변수 개수 상관 없다
client ---aop--- Controller main() --- V --- client -->
3) pointcut 표현식
• Advice 적용 범위 설정 > 표현식 사용
☑ execution 명시자
▪ Advice를 적용할 메소드 명시할때 사용
▪ execution(접근지정자 리턴타입 클래스이름패턴.메소드명 패턴(파라미터 패턴))
▪ 접근지정자 : 생략가능, 스프링 aop에서는 public 메소드만 적용가능
▪ 리턴타입 : * 모든 리텅타입
▪ 클래스 이름 패턴 : 패턴으로 명시가능, 뒤에 메소드명을 붙힐때는 . 포함하여 연결 (생략가능)
▪ 메소드명 패턴 : 패턴으로 명시 가능
▪ 파라미터 패턴 : 패턴으로 명시 가능
💡
* 모든~
.. 0개 이상
[Ex]
execution(public void set*(..))
// 리턴타입이 void인 메소드명이 set으로 시작하는 매개변수 개수 상관없음, 어떤 클래스건 노상관
execution(* test.ex01.package.*.*())
// 매개변수 없고, 접근지정자 생략, 리턴타입 상관 없고, test.ex01.package 패키지의 모든클래스중
모든 메소드 호출될때
execution(* test.ex01.package..*.*(..))
// 접근지정자 생략, 리턴타입 노상관, test.ex01.package 패키지와 하위패키지에 있는 모든클래스중
모든 메소드, 매개변수 개수 노상관
execution(* get*(*,*))
// 접근지정자 생략, 리턴타입 노상관, 메소드명 get으로 시작하는것, 매개변수 타입노상관 두개
execution(* read*(Integer,..))
// 접근지정자 생략, 리턴타입 노상관, 메소드명 read로 시작, 첫번째 매개변수 Integer이여야하고 이후 매개변수 노상관
* 명시자를 &&, || 연산자 이용하여 연결할 수도 있다.
expression="execution(...) && execution(...)"
☑ within 명시자
▪ 특정 타입에 속하는 메소드(범위)를 설정할때
| within(test.spring.mvc.HelloBean) | 이 클래스의 모든 메소드 호출시 |
| within(test.spring.mvc.*) | 패키지안의 모든 클래스의 모든 메소드 호출시 |
| within(test.spring.mvc..*) | 패키지와 하위 패키지에 있는 모든 메소드 호출시 |
☑ bean 명시자
▪ 스프링에서 추가적으로 제공하는 명시자로 스프링 빈 이름을 사용하여 정의
| bean(hello) | bean의 이름이 hello인 클래스의 메소드 호출될때... |
| bean(*hello) | bean의 이름이 hello로 끝나는 클래스의 메소드 호출될때... |
4. 어노테이션 기반 AOP
xml 기반 <aop:adpect, <aop:pointcut 태그로 설정
어노테이션은 @Aspect, @Pointcut 자바 코드위에 지정
[회원가입에 응용]
- 컨트롤러 빈 클래스 만들기 AopMemberController
- AOP Aspect 적용할 클래스 생성 MemberAspect, 클래스레벨 @Aspect
- aop-context.xml > MemberAspect 빈으로 등록, <aop:aspectj-autoproxy /> 설정
'basic > spring' 카테고리의 다른 글
| spring (0) | 2023.09.08 |
|---|---|
| [spring 11] Spring Test (0) | 2021.08.16 |
| [spring 09] 게시판 만들기 (0) | 2021.08.10 |
| [spring 09] Ajax (0) | 2021.08.10 |
| [spring 08] jQuery (0) | 2021.08.09 |