관점 지향 프로그래밍이란?
관점 지향 프로그래밍 (Aspect Oriented Programming)는 기존의 OOP로는 해결할 수 없는 횡단 관심사에 대해서 재사용 가능한 코드로 만들기 위해서 등장했다.
기존의 OOP로 웹 애플리케이션은 다음과 같이 프레젠테이션 계층, 서비스 계층, 데이터 액세스 계층으로 나눠 관심사를 분리했다.
이를 통해서 유지보수와 테스트를 유용하게 만들었다.
프레젠테이션 계층과 관련된 변경은 프레젠테이션 계층에서 구현된 코드에 국한되도록 코드를 구성했기 때문에 변경 점을 찾기 쉬웠고 서비스 계층과 데이터 액세스 계층도 마찬가지였다.
관심사의 분리를 통한 계층화는 성공적이었다.
하지만 이런 관심사의 분리를 이용할 수 없는 관심사들이 생겼다.
예를 들면 트랜잭션에 대한 관심사는 서비스 계층과 데이터 액세스 계층에 걸쳐서 발생하였기 때문에 이를 묶어내서 리팩토링하기는 어려웠다.
또한 로깅과 같은 작업도 프레젠테이션 계층, 서비스 계층, 데이터 액세스 계층 전역에 이뤄서 모두 발생하는 코드들이었다.
이 때문에 관점 지향 프로그래밍이 등장했다.
AOP는 기존의 OOP가 바라보던 시각이 아닌 다른 관점에서 보는 것이다.
기존의 OOP 관점에서 보았을 때는 해결할 수 없는 트랜잭션이나 로깅 처리에 대해서 효과적으로 묶어낼 수 있게 되었다.
여러가지 방법이 있겠지만 아주 기초적이고 단순한 방법으로 한번 살펴보겠다.
예시
다음과 같은 인터페이스와 구현체가 있다.
public interface AuthService{
public void signUp(UserDTO userDTO);
public void signIn(UserDTO userDTO);
}
public class AuthServiceImpl implements AuthService{
@Override
public void signUp(UserDTO userDTO){
// 회원가입 기능
}
@Override
public void signIn(UserDTO userDTO){
// 로그인 기능
}
}
다음의 코드에 트랜잭션을 수행하고자 한다면 이는 데이터 액세스 계층에 트랜잭션 기능을 전달하기 위한 코드를 추가해야 한다.
하지만 AOP에서는 다음과 같이 추가해줄 수 있다.
public class AuthServiceTransaction implements AuthService{
AuthService authService;
@Autowired
public void AuthService(AuthService authService){
this.authService = authService;
}
@Override
public void signUp(UserDTO userDTO){
// 회원가입 기능에 대한 트랜잭션 코드
this.authService.signUp(userDTO);
// 트랜잭션 종료
}
@Override
public void signIn(UserDTO userDTO){
// 로그인 기능에 대한 트랜잭션 코드
this.authService.signIn(userDTO);
// 트랜잭션 종료
}
}
사용자는 AuthService의 구현체로 AuthServiceImpl을 통해서 회원가입과 로그인을 수행하지 않는다.
사용자는 AuthServiceTransaction을 통해서 회원가입과 로그인 기능을 수행하는데 실제로 이는 AuthServiceTransaction은 트랜잭션을 수행하기 위한 로직을 수행하고 실제 로그인과 회원가입은 AuthServiceImpl을 통해 사용된다.
AuthService의 사용자 Controller는 다음과 같다.
@RestController
public class AuthController{
// AuthService의 구현체는 AuthServiceTransaction을 사용
private AuthService authService;
public AuthController(AuthService authService){
this.authService = authService;
}
public void signUp(UserDTO userDTO){
this.authService.signUp(userDTO);
}
public void signIn(UserDTO userDTO){
this.authService.signIn(userDTO);
}
}
AOP는 다음과 같은 그림으로 동작한다.
'Spring' 카테고리의 다른 글
[Spring Test] Mockito when()과 given() 차이 (0) | 2024.01.29 |
---|---|
[Spring Boot] 스프링 부트 HTTPS 적용 방법 (1) | 2024.01.26 |
[Spring Boot] Interceptor 활용 (1) | 2024.01.25 |
[Spring Boot] application.yml profile 기능 (1) | 2024.01.25 |
[Spring Boot] 스프링 부트에서 Spring MVC를 자동 설정하는 과정 (0) | 2024.01.20 |