본문 바로가기

spring

[Spring] 스프링의 삼각형: IoC/DI, AOP, PSA를 통한 클린 코드와 유지보수성 향상

[배경]

 스프링 프레임워크의 IoC/DI, AOP, PSA는 소프트웨어 개발의 효율성을 높이기 위해 발전해온 기술들입니다. IoC/DI는 코드의 결합도를 낮추고, AOP는 공통 관심사를 모듈화하며, PSA는 성능 분석과 모니터링을 지원합니다. 이러한 개념들은 스프링 프레임워크가 지속적으로 발전하면서 소프트웨어 개발의 요구를 충족시키기 위해 통합되었습니다. 

 


 

[내용]

1. 스프링 삼각형과 설계

  스프링을 이해하려면 POJO(Plain Old Java Object)를 기반으로 스프링 삼각형이라는 녀석을 알아야 합니다. 스프링 삼각형은 Ioc/DI, AOP, PSA라고 하는 스프링의 3대 프로그래밍 모델로 이루어져 있습니다. 스프링 프레임워크는 이러한 스프링 삼각형과 설계정보를 바탕으로 객체지향 원리를 토대로 깔끔하고 유지보수가 용이한 프로그래밍을 하는 데 기여하고 있습니다.

 

2. POJO

 Plain Old Java Object, 간단히 POJO는 말 그대로 해석을 하면 오래된 방식의 간단한 자바 오브젝트라는 말로서 Java EE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 "무거운" 객체를 만들게 된 것에 반발해서 사용되게 된 용어입니다. 쉽게 말해 POJO는 자바 언어 사양 외에 어떠한 제한에도 묶이지 않은 자바 오브젝트라고 할 수 있습니다. 객체 지향적인 원리에 충실하고 환경과 기술에 종속되지 않으며 필요에 따라 재활용할 수 있는 방식으로 설계된 자바 오브젝트를 뜻합니다. POJO를 3대 프로그래밍 모델에 맞게 관계를 맺고 동작하도록 설계하고 그러한 정보를 설계정보에 정의해놓는데 이 것이 스프링의 핵심이라고 볼 수 있습니다.

 

3. Ioc/DI란?

  Ioc(Inversion of Control / 제어의 역전)는 메소드나 객체의 호출작업을 개발자가 하는 것이 아니라 외부(프레임워크)에서 하는 것입니다. 예를 들어 서블릿 클래스의 객체 생성, 메소드 호출 등의 객체에 대한 전체적인 관리를 컨테이너가 대신 해주며 개발자는 프레임워크에 필요한 부품을 개발하고, 조립하는 방식의 개발을 하게 되는 것입니다. 결국 조립된 코드의 최종 호출이 개발자에 의해 제어되는 것이 아니라, 프레임워크의 내부에서 결정하기 때문에 '제어의 역전'이라고 표현합니다.

 DI(Dependency Injection / 의존성 주입)를 설명하기 전에 의존성이 뭔지 알아야합니다. 간단히 말해 어떠한 객체 안에 다른 객체를 참조하고 있다면 의존관계에 있다고 표현합니다. 전체(다른 객체를 참조하는 객체)가 부분(참조당하는 객체)에 의존한다고 표현할 수 있습니다. 의존관계에 있는 객체에 대하여 new 생성자를 이용하는 방법(직접 의존성 해결)과 외부에서 객체를 받는 방법(의존성 주입)이 있는데 외부에서 의존관계를 해결해주는 것이 바로 DI(의존성 주입)입니다.

 

4. AOP란?

  Aop(Aspect Oriented Programming / 관점 지향 프로그래밍)은 어원 그대로 관점에 따라 프로그래밍을 하는 것입니다. 스프링 DI가 의존성에 대한 주입이라면 스프링 AOP는 로직(code) 주입이라고 할 수 있습니다.

  예를 들어 위의 그림을 보면 입금, 출금, 이체 모듈에서 로킹, 보안, 트랜잭션 기능이 반복적으로 나타나는 것을 볼 수 있다. 이처럼 다수의 모듈에 공통적으로 나타나는 부분이 존재하는데 이를 횡단 관심사(cross-cutting-concern)이라 합니다.
또 다른 예시로 데이터베이스 연동 프로그램을 작성할 때 어떠한 연산을 하던지 Connection, Statement, ResultSet 등의 객체 생성에 대한 코드를 공통적으로 작성합니다. 이게 바로 횡단 관심사입니다.

 AOP는 모듈별로 다른 핵심 관심사와 모듈별로 반복되어 중복해서 나타나는 횡단 관심사를 분리하여 관점에 따라 프로그래밍을 합니다. 이를 통해 객체지향 설계원칙 중 SRP(Single Responsibility Principle / 단일 책임 원칙)을 실천할 수 있습니다.

 다음은 AOP 용어에 대해서 알아보겠습니다.

  • Pointcut : Aspect 적용 위치 지정자, where의 의미를 가집니다.
  • JoinPoint : 연결 가능한 지점, 즉 Aspect 적용이 가능한 지점을 뜻합니다.
  • Advice : 조언, what과 when을 의미합니다.
  • Aspect : 관점, Advisor의 집합체를 뜻합니다. Aspect = Advice들 + Pointcut들



    간단하게 코드로 보겠습니다.

    그림에서 1번이 Pointcut입니다. Pointcut의 내용을 만나면 Aspect를 적용하라는 의미입니다. 그래서 where? 어디서?? Aspect를 적용할 지 알려주는 역할을 하기 때문에 Aspect 적용 위치 지정자라고 부릅니다.
    2번은 JointPoint입니다. 이 코드에서의 JointPoint는 Pointcut인 public void aop002.Boy.runsomething()입니다. 앞에서 Aspect가 적용가능한 지점이라고 했는데 스프링 AOP에서는 인터페이스 기반이기 때문에 JointPoint는 메소드만 가능합니다!!
    3번은 Advice입니다. @Before은 언제 Aspect를 적용할지를, public void before(~~) {~~}은 무엇을 Aspect로 적용할지를 알려줍니다.
    결국 어디서(Pointcut 지점에서) 언제쯤(Pointcut지점 전 또는 후 등등)에 무엇을(횡단 관심사를) 실행시킬 지를 지정하는 게 바로 MyAspect 클래스이며 이를 @Aspect로 스프링 프레임워크에게 알려주는 것입니다.

5. PSA란?

  PSA(Portable Service Abstraction / 일관성 있는 추상화)는 일관성 있는 방식으로 서비스 추상화를 해주는 것입니다. 어댑터 패턴을 적용해 같은 일을 하는 다수의 기술을 공통의 인터페이스로 제어할 수 있게 한 것을 서비스 추상화라고 합니다. 어댑터 패턴을 비롯한 디자인 패턴은 다음 시간에 자세히 설명하도록 하겠습니다.
예를 들어 JDBC라고 하는 표준 스펙이 있기에 오라클, MySQL, MS-SQL 등과 같은 다양한 DBMS의 종류에 상관없이 Connection, Statement, ResultSet을 이용해 공통된 방식으로 코드를 작성할 수 있습니다.
또한 스프링 프레임워크에서도 이를 활용하고 있습니다. 다양한 종류의 OXM(Object XML Mapping / 객체와 XML 매핑) 기술들이 제공하는 API는 제각각인데 이러한 API를 위한 어댑터를 스프링이 제공함으로써 실제로 어떤 OXM 기술을 쓰든 일관된 방식으로 코드를 작성할 수 있게 지원합니다. 그리고 하나의 OXM 기술에서 다른 OXM 기술로 변경할 때 큰 변화없이 세부 기술을 교체해서 사용할 수 있게 해줍니다.

 


[결론]

 스프링 삼각형의 세 가지 핵심 요소인 IoC/DI, AOP, PSA는 개발자가 보다 효율적으로 소프트웨어를 개발할 수 있도록 돕는 중요한 개념입니다. 이러한 개념들을 활용하면 코드의 결합도를 낮추고, 유지보수성을 높이며, 시스템 성능을 최적화할 수 있습니다. 따라서, 스프링 프레임워크를 사용하는 모든 개발자는 이들 개념을 깊이 이해하고 활용할 수 있어야 합니다. 개발자들은 더 나은 설계를 만들고, 코드를 보다 유연하고 재사용 가능하게 만들 수 있습니다. 스프링을 통한 이러한 접근 방식은 장기적으로 소프트웨어 개발의 성공과 유지보수성에 큰 차이를 가져올 것입니다.


[출처 및 참조]