Spring - SPEL(SPring Expression Language)
AOP(Aspect-Oriented Programming)
- 프로그래밍에서 발생하는 공통적인 기능을 구현할 때 코드가 중복되지 않도록 모듈화 하는 프로그래밍 기법을 관점지향적 프로그래밍(AOP)라고 한다.
- 기능별로 Aspect를 만들어 독립적으로 정의하고, 정의된 기능을 어디서 적용해야하는지 명시함으로서 클래스 내부에 구현할 필요 없이 기능을 사용할 수 있다.
- Java에서는 다중 상속이 불가능하여 AOP가 도입되었다.
AOP의 용어와 개념
- Aspect - 공통적인 기능을 정의해놓은 하나의 모듈. Advice와 Pointcut이 포함되어 있다.
- Advice - 모듈이 동작할 기능을 Advice라고 한다. ‘언제’ Aspect가 수행될 것인지 @Around, @Before와 같은 정보를 통해 나타낸다.
- Pointcut - Advice가 적용될 위치에 대한 정보. Target에 대한 특정 메소드의 실행 시점을 의미한다.
- Join Point - Advice가 합류하는 지점. pointcut보다 자세한 적용지점을 의미한다.
- Target - Aspect의 기능이 적용될 객체
- Weaving - Aspect를 Traget에 연결시켜 OOP로 만드는 과정을 의미.
- Cross-Cutting-Concern (흩어진 관심사) - 소스 코드상에서 다른 코드에 반복적으로 발생하는 부분을 의미. 이러한 관심사들을 Aspect로 모듈화하고 분리하여 재사용하는 것이 AOP의 주 목표이다.
※ AOP는 흩어진 관심사를 Aspect로 만들어 사용하는 것이므로 다수의 Aspect를 사용하는 것은 좋지 못한 사용방법이다.
자바에서의 AOP
- 자바에서 사용할 수 있는 AOP는 크게 AspectJ, 스프링 AOP로 나누어 설명할 수 있다.
Spring AOP
- Spring IOC를 통해 애플리케이션에서 흔히 발생하는 문제에 대해 해결하는 것을 목적으로 사용되는 구현체이다.
- 모든 AOP기능을 제공하지 않고 스프링 Bean에만 AOP를 적용할 수 있다.
- Dynamic Proxy(동적으로 Proxy 객체를 생성하는 방법) 기법이 적용된다.(Target 객체에 대한 호출을 Proxy가 Interrupt하여 객체의 기능에 Advice 수행을 추가한다.)
- 기존 Bean을 대체하는 Dynamic Proxy Bean을 생성하므로 클라이언트 코드에 변경이 없으며 Method Join Point만을 지원한다.(Target의 Method가 호출되는 런타임 시점에만 Weaving이 사용됨)
Spring AOP 적용
- 스프링 AOP를 사용하기 위해서는 다음의 의존성을 추가해야 한다.
1 | <dependency> |
- Aspect 모듈은 XML을 이용한 구현, @Aspect 어노테이션을 이용한 구현 두가지가 있으며 Aspect 빈의 메소드에 Advice와 Pointcut 를 등록하여 모듈이 동작한다.
Spring AOP Advice 타입
- Spring AOP에서 정의할 수 있는 Advice 어노테이션은 다음과 같다.
@Around - joinPoint 이전/이후에 모두 Advice가 수행되도록 한다.
@Before - joinPoint 이전에 Advice가 수행되도록 한다.
@After - joinPoint 이후 Advice가 수행되도록 한다.
@AfterReturning - joinPoint가 정상적으로 반환/수행된 후 Advice가 수행되도록 한다.
@AfterThrowing - joinPoint 수행 중 예외가 던져질 경우 Advice가 수행되도록 한다.
Spring AOP PointCut
- Spring AOP에서 자주 사용되는 포인트 컷은 다음과 같으며 각 표현식은 &&, ||, !로 조합할 수 있다.
execution( (접근지정자) (패키지).(클래스/인터페이스).(메소드)(..) ) - 메소드의 실행을 PointCut으로 등록한다.
within((패키지).(클래스/인터페이스)) - 특정 타입에 속하는 매소드를 PointCut으로 등록한다.
bean (빈 이름) - 해당 이름을 갖는 Bean을 PointCut으로 등록한다.
this ((패키지).(인터페이스)) - 해당 인터페이스를 구현하는 프록시 객체 메소드를 PointCut으로 등록한다.
target ((패키지).(인터페이스)) - 해당 인터페이스를 구현하는 대상 객체의 메소드를 PointCut으로 등록한다.
args (타입) - 해당 타입을 인자로 갖는 메소드를 PointCut으로 등록한다.
@annotation (어노테이션) - 해당 어노테이션이 선언된 메소드를 PointCut으로 등록한다.
1 |
|
AspectJ
- 완전한 AOP를 제공하는 것을 목적으로 하는 기술
- AspectJ는 다음과 같은 시간에 Weaving을 사용할 수 있다.
- 컴파일 타임 - Aspect 코드와 애플리케이션의 코드를 모두 입력받아 AspectJ 컴파일러가 클래스를 생성
- 컴파일 전 - 이미 존재하는 class 파일과 jar 파일을 입력받아 클래스 생성.
- 로드 타임 - class파일과 jar파일을 입력받아 클래스를 생성하지만 class 파일이 JVM에 로드된 후 클래스 생성이 이루어진다.
- 메소드 실행에 대해서만 Join Point를 적용할 수 있는 Spring AOP와 달리 다음의 Join Point를 설정할 수 있다.
- 메소드 호출/실행
- 생성자 호출/실행
- Static 초기화 실행
- 객체 초기화
- 필드 참조
- 필드 값 변경
- Handler 실행
- Advice 실행
- 런타임이 아닌 컴파일/로드 타임에 Weaving이 사용되므로 런타임 Weaving을 사용하는 Spring AOP에 비해 빠르지만 AspectJ 컴파일러, Aspect 자바 툴을 요구하고 라이브러리들을 재 패키징해야하는 복잡함이 있다.