S E P H ' S

[Spring] 3. Spring 핵심 3대요소 (IoC/DI, AOP, PSA) 본문

Programing & Coding/Spring

[Spring] 3. Spring 핵심 3대요소 (IoC/DI, AOP, PSA)

yoseph0310 2023. 5. 7. 20:35

Spring 핵심 3대 요소

스프링 프레임워크는 POJO (Plain Old Java Object) 프로그래밍을 지향한다. 순수 Java만을 통해서 생성한 객체를 말하는데 이를 지향하는 이유는 외부 기술이나 규약의 변화에 얽매이지 않고 유연하게 변화와 확장에 대처할 수 있다. 이를 통해 비즈니스 로직을 구현하면 객체지향 설계를 제한없이 적용할 수 있으며 코드가 단순해져 테스트와 디버깅이 쉬워진다. 이처럼 비즈니스 로직을 구현하는데에 POJO를 적극적으로 활용하는 패러다임을 POJO 프로그래밍이라고 한다. 이번 포스팅은 POJO 프로그래밍을 위해 스프링이 지원하는 기술인 IoC/DI, AOP, PSA에 대해 간략하게 알아보는 포스팅이 될 것이다.

 

1. IoC / DI (Inversion of Control / Dependency Injection) 제어의 역전, 의존성 주입

지난 포스팅에서 다뤘지만 가장 중요한 내용이기 때문에 복습 차원에서 한번 더 살펴보자. 두 가지 개념은 함께 살펴보면 이해가 훨씬 빠를 것이다. DI 에 대해서 먼저 설명했을 때, 의존관계를 알 필요가 있다고 했다. 지난번처럼 코드를 한 번 살펴보자.

 

public class PizzaChef {
	private PizzaRecipe pizzaRecipe;
    
        public PizzaChef() {
            this.pizzaRecipe = new PizzaRecipe();
        }
}

 

PizzaChef 객체는 PizzaRecipe 객체에 의존관계가 있다. PizzaRecipe의 상태나 특정 값이 변하게 되면 PizzaChef 또한 변화하게 된다. 이때, A는 B와 의존관계라고 한다. 이런 경우에는 두 클래스 간 결합성이 높다는 것, 객체들 간의 관계가 아닌 클래스 간의 관계가 맺어진다는 것이다. 피자 셰프가 새로운 레시피 클래스를 사용해야 하면 피자 셰프의 생성자를 변경해야 하고 매번 레시피가 추가되면 코드 수정이 불가피 하므로 유연성이 떨어진다. 또한 추상화(인터페이스)에 의존해야 한다는 DIP(Dependency Inversion Principle) 원칙에도 위배된다.

 

이를 DI를 통해 해결할 수 있다. DI는 의존관계를 외부에서 결정 및 주입해주는 것을 말한다. Spring에서는 이러한 DI를 스프링 컨테이너(BeanFactory를 확장한 ApplicationContext)에서 관리한다. DI를 통해 PizzaChef 클래스가 직접 클래스를 생성하는 것이 아닌 스프링 컨테이너가 생성한 클래스를 가져와 사용할 수 있는 것이다. 이 때 클래스를 생성하고 PizzaChef에게 필요한 객체를 인자로 전달하는 이 행위 자체는 개발자가 직접하지 않는다. 이 행위는 스프링 컨테이너가 한다. 이러한 것을 제어의 역전, IoC라고 한다. 

 

다시 정리하자면 개발자가 아닌 스프링이 어떤 클래스가 사용할 객체를 생성하여 의존 관계를 맺어주는 것을 IoC라고 하고 그 과정에서 하나의 클래스를 다른 클래스의 생성자를 통해 주입해주는 것을 DI라고 한다.

 

 

2. AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)

관점 지향이라는 말대로 어떤 로직을 볼때 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 모듈화(어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것)하겠다는 것이다.

 

결제 시스템을 예시로 들자면 핵심적인 관점은 결제가 되는 비즈니스 로직, 부가적인 관점은 결제(비즈니스 로직)가 이루어지기 위해 행해지는 데이터베이스 연결, 로깅 등등이 될 수 있다. 그림을 보면서 살펴보도록 하자.

 

그림과 같이 클래스 A, B, C에서 공통적으로 나타나는 색 블록들은 중복되는 메소드나 필드, 코드 등을 의미한다. 이때 만약 클래스 A의 초록색 부분을 수정해야 한다면 클래스 B, C의 부분도 일일이 찾아 수정해야 하는 불편함이 있다. 이는 SOLID 원칙(단일 책임 원칙)을 위배하며 유지보수를 어렵게 만든다. 이렇게 코드 상에서 계속 반복적으로 사용되는 부분들을 흩어진 관심사(CrossCutting Concerns)라고 한다.

 

AOP 에서 각 관점을 기준으로 로직을 모듈화 한다는 것은 흩어진 관심사를 모듈화 하겠다는 것이다. 그림과 같이 Aspect X, Y, Z와 같이 모듈화로 코드를 구성해둔 다음, 필요한 곳에서 사용하면 되는 것이다. 간단히 한 줄로 요약하자면 "AOP는 공통 기능을 재사용하는 기법"이다.

 

AOP 관련 용어

Aspect :
흩어진 관심사를 모듈화 한 것
Target :
Aspect를 적용하는 곳. 클래스, 메소드 등
Advice :
실질적으로 어떤 일을 해야 할지에 대한 것, 실질적인 부가기능을 담은 구현체
Join Point :
Advice가 적용될 위치 혹은 끼어들 수 있는 시점. 메소드 진입 시점, 생성자 호출 시점, 필드에서 꺼내올 시점 등 개입할 시점을 의미. 스프링에서 Join Point는 메소드 실행 시점을 의미한다.
Point Cut :
Join Point의 상세한 스펙을 정의한 것. "A란 메소드의 진입 시점에 호출할 것"과 같이 구체적으로 Advice가 실행될 시점을 정함.

 

AOP 적용 방법

1. 컴파일 타임 적용 :
컴파일 시점에 바이트 코드를 조작하여 AOP 가 적용된 바이트 코드를 생성하는 방법.
2. 로드 타임 적용 :
순수하게 컴파일 한 뒤, 클래스를 로딩하는 시점에 클래스 정보를 변경하는 방법
3. 런타임 적용 :
스프링 AOP가 주로 사용하는 방법. A라는 클래스 타입의 Bean을 만들 때, A 타입의 Proxy Bean을 만들어 Proxy Bean이 Aspect 코드를 추가하여 동작하는 방법.

 

여기까지 AOP를 알았다면 핵심 키워드는 감을 잡았을 것이다. AOP는 공통적으로 사용되는 기능, 즉 부가 기능을 재사용하는 기법이라는 것. 이를 해내기 위해 AOP는 프록시 패턴, 데코레이터 패턴을 사용한다.

 

3. PSA (Portable Service Abstraction) 일관된 서비스 추상화

PSA는 환경의 변화와 관계없이 일관된 방식의 기술로의 접근 환경을 제공하는 추상화 구조를 말한다. 이는 POJO 원칙을 철저히 따른 Spring의 기능으로 Spring에서 동작할 수 있는 Library들은 POJO 원칙을 지키도록 PSA 형태의 추상화가 되어있음을 의미한다. PSA가 적용된 코드라면 코드가 변경되지 않고도 다른 기술로 간편하게 바꿀 수 있는 확장성을 지니게 된다.

 

쉽게 말해 개발자가 개발시에는 내부적으로 어떻게 동작하는지는 살펴볼 일이 거의 없다. 내부적으로 작동하는 기능들을 숨기고, 추상화하여 개발자에게 제공하기 때문이다. Spring은 Spring Web MVC, Spring Transaction, Spring Cache 등의 다양한 PSA를 제공한다.

 

기본적으로 Spring에서는 PlatformTransactionManager 이라는 최상위 Manager를 사용하고, 각각 사용자의 선언에 따라서 JPATransactionManager, DatasourceTransactionManager, HibernateTransactionManager등을 상황에 맞게 의존성 주입을 받아 사용한다.

 

Spring이 Spring Web MVC에 대한 PSA를 제공한다고 했다. 추후에 다뤄볼 Servlet 기반으로 Application을 활용하지만 Spring을 사용한다면 개발자는 Servlet에 대한 코드를 직접 다룰 필요가 없다. @Controller, @GetMapping 등의 어노테이션만 잘 활용한다면 보이지 않는 곳에서 Spring이 원하는 기능을 편리하게 처리해준다. 즉 PSA는 서비스 추상화를 통해서 개발자에게 인터페이스를 제공하여 편리성을 극대화 할 수 있는 기법이다.

 


정리

이번 포스팅을 정리하면서 내용이 많이 빈약함을 느낄 수 있었다. IoC/DI에 이어서 AOP, PSA가 핵심 원리이니 만큼 깊게 다뤄봐야할 필요가 있다. 사실 한 포스트에 AOP와 PSA를 다룰 수 있을거라고 생각한 필자의 착각이었다. 스프링의 3대 원칙으로 이런 것들이 있다 정도로 이번 포스팅을 마치고 AOP, PSA에 대해서 더욱 깊게 다뤄볼 것이다.

 

 

 

출처

 

[Spring] AOP(Aspect Oriented Programming)란? 스프링 AOP란?

AOP (Aspect Oriented Programming)란? AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그

code-lab1.tistory.com

 

[Spring] PSA란?

이전 포스팅까지 Spring Triangle 중 IOC와 AOP에 대하여 다루어 보았습니다. https://chanho0912.tistory.com/8?category=866707 [SpringBoot] IOC(Inversion Of Control), DI(Dependency Injection)이란? 지난 포스팅까지 SpringBoot의 작

chanho0912.tistory.com