일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- virtualization
- computer science
- 백엔드
- 배포
- JPA
- Container
- 스프링 배치
- CI/CD
- mysql
- 웹 서버
- 컨테이너
- spring boot
- 스프링
- web server
- Java
- 도커
- 영속성 컨텍스트
- ORM
- HTTP
- Spring Security
- 스프링 부트
- vm
- 데이터베이스
- spring batch
- Spring
- CS
- spring cloud
- 스프링 시큐리티
- 가상화
- 자바
- Today
- Total
개발 일기
[Spring Boot] Spring 3대 특징(Spring 삼각형) 3 - 관점 지향 프로그래밍(AOP) 본문
[Spring Boot] Spring 3대 특징(Spring 삼각형) 3 - 관점 지향 프로그래밍(AOP)
개발 일기장 주인 2024. 3. 13. 16:05전 게시글에서POJO를 달성하기 위한 3가지 스프링 핵심 특징인 IoC/DI, AOP, PSA 중 IoC/DI에 대해 알아봤었다. 이번 게시글에서는 나머지 AOP에 대해서 알아보자
관점 지향 프로그래밍 (Aspect Oriented Programming - AOP)
AOP 도입 배경( feat. 횡단 관심사)과 AOP 개념
AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)는 횡단 관심사(cross-cutting concerns)를 다루는 프로그래밍 패러다임이다.
이때 횡단 관심사란 여러 모듈이나 기능에서 공통적으로 나타나는 관심사를 말하며, 로깅, 보안, 트랜잭션 관리 등이 여기에 해당한다.
AOP를 사용하면 이러한 공통된 로직을 핵심 비즈니스 로직에서 분리하여 관리할 수 있어 코드의 중복을 줄이고, 유지 보수 및 확장성을 향상시킬 수 있다.
우선 횡단 관심사를 예시를 통해 자세히 이해해 보자. 아래와 같이 회원 리스트에 회원을 추가하고 조회하고 제거하는 비즈니스 로직이 있다.
public class MemberService {
// 회원 등록
public void addMember(String memberName) {
/*
비즈니스 로직 생략
*/
members.add(memberName);
System.out.println("회원 추가: " + memberName);
}
// 회원 제거
public void removeMember(String memberName) {
/*
비즈니스 로직 생략
*/
members.remove(memberName);
System.out.println("회원 제거: " + memberName);
}
// 회원 조회
public List<String> getMembers(String memberName) {
/*
비즈니스 로직 생략
*/
return members;
}
}
지금은 간단하게 생략되어있지만 각각은 요구 사항에 맞게 구체적인 비즈니스 로직이 구현되어 있을 것이다.
그런데 회원 리스트에 회원을 등록하는 메소드의 실행시간을 구해달라는 요청을 받았고 아래 코드와 같이 시간을 출력하여 확인할 수 있다.
// 회원 등록
public void addMember(String memberName) {
long start = System.currentTimeMillis(); // 시작 시간 체크
/*
비즈니스 로직 생략
*/
members.add(memberName);
System.out.println("회원 추가: " + memberName);
long end = System.currentTimeMillis(); // 종료 시간 체크
System.out.println("회원 등록 처리 시간: " + end - start + "ms"); // 실행 시간 출력
}
여기 까지는 문제가 없다. 이번에는 회원 관리 관련 로직(회원 등록, 제거, 조회) 전체에서 이 메소드 실행 시간을 출력해달라고 요청이 드어왔다. 이러한 요청은 회원 관리 관련 로직 뿐만아니라 해당 서비스 내에 모든 메소드에서 요구될 수 있다.
그러면 이럴때마다 각 메소드마다 시작 시간과 종료 시간을 체크하여 실행 시간을 출력하는 로직을 일일이 다 넣어주어야하지만 이것은 너무 비효율적인 단순 작업의 반복이다.
이러한 문제를 해결하기 위해 AOP라는 것을 도입하게 됐다.
은행 어플리케이션 예시
또 다른 그림 예시로 이해해보자
여러 타 블로그 글을 봤을 때 가장 흔한 예시가 바로 은행 어플리케이션 로직이였다.
계좌이체, 입출금, 이자계산은 은행 어플리케이션에 있어서 핵심 비즈니스 로직이지만 로깅, 보안, 트랜잭션은 각각의 핵심 비즈니스 로직에서 공통적으로 동작하는 부가적인 기능으로 볼 수 있다.
위와 같이 로깅, 보안, 트랜잭션 그리고 위에서 회원 관리 로직에서의 메소드 실행시간 등(횡단 관심사)을 단순히 각 메소드마다 넣어주게 되면 공통된 로직이 모든 비즈니스 로직마다 반복되어 작성된다. 그렇게 되면 이 횡단 관심사의 요구사항(로직)이 변경될 경우 각 메소드마다 찾아가서 일일이 다 변경해줘야하는 등 유지보수성에 좋지않으며 코드의 반복으로 코드의 양도 증가하고 확장성에 불리할 것이다.
그래서 이와 같이 AOP라는 새로운 패러다임을 도입하여 비즈니스 로직과 공통 로직(횡단 관심사)을 분리하고 비즈니스 로직을 사용할 공통 로직에 매핑해주는 방식을 채택하게된 것이다.
그래서 AOP를 정의해보자면?
AOP는 Aspect Oriented Programming, 즉 관점 지향 프로그래밍으로 비즈니스 로직으로 부터 횡단 관심사(cross-cutting concern)의 분리를 하여 이를 모듈화시키는 것이 목적인 프로그래밍 패러다임이다. AOP는 특정 기능이나 관심사가 여러 객체나 함수를 가로질러 걸쳐 있는 경우 이를 분리하여 관리가 수월하게 도와준다.
장점
- 전체 코드 기반에 흩어져 있는 관심 사항이 하나의 장소로 응집한다.(모듈화)
- 자신의 주요 관심사항에 대한 코드만 포함하고 있기 떄문에 코드가 깔끔해진다.(코드의 중복 감소, 가독성 증가, 유지보수성 증가)
- 객체 지향적으로 코드를 짤 수 있게 돕기떄문에 AOP는 OOP를 돕는다.
즉, 코드의 반복을 줄이며 변화에 강하고 유지보수성 및 확장성 증가
AOP 용어 정리
- Target
부가 기능(횡단 관심사)을 부여할 대상
핵심 비즈니스 로직을 구현한 클래스
ex) MemberService - Aspect
여러 객체에 공통적으로 적용되는 횡단 관심사
즉, 횡단 관심사를 모듈화 한 것
여러 개의 Adivice와 여러 개의 PointCut의 결합체 - Advice
어느 횡단 관심사를 언제 Target에 적용할 것인지
각 관심사가 하는 실제 부가기능을 담은 구현체
ex) 메소드 실행 시간 체크 등 - Join Point
Advice가 적용될 수 있는 위치
ex) MemberService의 메소드 실행 단계 - Pointcut
Advice를 적용할 JoinPoint를 선별하는 작업
JoinPoint의 부분 집합으로 실제 Advice가 적용되는 JoinPoint를 나타냄
ex) 어떤 메소드에 적용할 것인가? - Weaving
JoinPoint를 Advice에 적용하는 방법
스프링 AOP는 Runtime Weaving을 사용하여 런타임 중에 Advice를 적용해준다.
스프링에서의 AOP 동작 과정
콩하나의 스프링 AOP 유투브 영상을 참고했다.
스프링에서는 BeanPostProcessor(빈 후처리기)를 통해 AOP를 적용한다.
생성된 빈 객체를 스프링 IoC 컨테이너에 등록하기 전에 이 생성된 객체를 조작하는 객체로 도식화해보면 아래와 같다.
(1) 빈 객체를 생성한 뒤 빈 후처리기로 전달
(2) Advisor 내의 PointCut을 이용해 전달받은 빈이 프록시 적용 대상인지 확인
(3) 프록시 생성 대상 빈들을 대상으로 프록시 객체 생성
(4) 프록시를 생성한 빈이라면 프록시 객체를, 프록시를 생성하지 않은 빈이라면 그냥 빈을 반환한다.
(5) 빈 후처리기에 전달받은 객체를 컨테이너의 빈으로 등록한다.
프록시(Proxy)
원본 객체를 감싼 객체로, 스프링 AOP에서는 부가기능을 추가할때 사용하는 패턴이다.
(스프링 AOP 구현 예시와 동작 방법에 대해서는 직접 코딩해보면서 추가로 보충해야할 것 같다. AOP가 뭔지에 대해서는 이해했으니 넘어가고 추후에 추가적으로 보충하자.)
'Back-End > Spring' 카테고리의 다른 글
[Spring Boot] CGI, Servlet, Front Controller, Spring Web MVC (0) | 2024.05.02 |
---|---|
[Spring Boot] Spring MVC - 구조 이해 (0) | 2024.05.02 |
[Spring Boot] Spring 3대 특징(Spring 삼각형) 2 - 의존성 주입(DI)과 제어의 역전(IoC) (1) | 2024.03.13 |
[Spring Boot] Spring 3대 특징(Spring 삼각형) 1 - POJO(Plain Old Java Object) (0) | 2024.03.09 |
[Spring Boot] Spring 생태계와 본질 (1) | 2024.03.08 |