본문 바로가기
CodeStatesBootCamp/Review

Section 2 - Unit 7 : Spring Framework 기본 Review

by JKROH 2023. 3. 31.
반응형
Review 에서는 학습한 내용을 다시금 기록합니다.
Unit Review는 학습한 내용 중 기존에 알고 있었지만 정확하게 이해하지 못하던 정보와 새롭게 알게된 정보를 기록합니다. 추가적인 설명을 요하는 부분은 댓글로 남겨주세요.
Section Review는 전반적인 Section을 되돌아보고 학습했던 시간과 과정, 내용을 총괄하여 기록합니다.

Spring Framework 특징

* POJO (Plain Old Java Object)

  • IoC / DI, AOP, PSA는 스프링의 가장 핵심이 되는 세 가지 방법론이다.
  • POJO는 이들에 둘러쌓여있다. 즉, 위의 세 방법을 통해 POJO를 달성할 수 있다.

- 그래서 POJO가 뭔데?

  • POJO는 Plain Old Java Object의 줄임말로, 말 그대로 Java로 생성하는 순수한 객체를 의미한다.
  • 스프링이 자바 기반 프레임워크이기 때문에 그냥 작성하면 될 것 같지만 그렇지 않다.
  • POJO 프로그래밍이라고 불리기 위해선 크게 두 가지의 기본 규칙을 지켜야 한다.
    • 자바나 자바 API 에 정의된 것 이외의 기술이나 규약에 얽매이면 안된다.
      • 예를 들어, 인터페이스를 구현하거나 다른 객체를 상속 받은 객체는, 해당 기술에 종속적이게 된다. 반드시 상위 객체를 기준으로 객체를 설계하고 유지보수해야 하기 때문이다.
    • 특정 환경에 종속적이지 않아야 한다.
      • 외부 라이브러리를 사용하다가 다른 API로 교체해야 한다면 해당 라이브러리가 사용된 코드를 모두 수정해야한다.

- POJO 프로그래밍은 왜 필요한가

  • 객체지향적 설계를 제한 없이 적용할 수 있다.
  • 변화와 확장에 유연하고 재사용이 가능한 코드의 작성이 가능하다.
  • 테스트 코드를 작성하기 쉽다.

 

* IoC (Inversion of Control)

- IoC란?

  • 일반적인 콘솔 프로그램의 경우, 개발자가 작성한 코드의 순서대로 코드가 진행된다. 즉, 개발자가 애플리케이션 흐름의 주도권을 쥐고 있는 것이다.
  • 반면 프레임워크는 애플리케이션 흐름의 주도권을 가져간다.
  • 이렇게 애플리케이션 흐름의 주도권이 뒤바뀐 것을 IoC라고 한다.

- 자바 웹 애플리케이션에서 IoC가 적용되는 예시

  • 서블릿 컨테이너는 서블릿 기반의 애플리케이션을 웹에서 실행시키기 위한 서비스다.
  • 일반적인 콘솔 애플리케이션은 메인 메서드가 실행되면서 프로그램이 실행되고, 메인 메서드가 종료되면서 프로그램이 종료된다.
  • 그러나 서블릿 컨테이너의 경우 별도의 메인 메서드가 없다.
  • 대신, 서블릿 컨테이너 내의 컨테이너 로직(service() 메서드)에서 서블릿을 직접 실행시킨다.
  • 즉, 개발자가 아니라 서블릿 컨테이너에서 전체적인 프로그램 흐름의 주도권을 쥐고 있는 것이다.
  • 스프링에는 IoC개념이 DI를 통해 이루어져있다.

 

* DI (Dependency Injection)

- 의존 주입이란?

  • 어떤 객체가 존재하기 위해선 반드시 다른 객체가 존재할 필요가 있을 때가 있다.
  • 예를 들어, [결제] 를 하기 위해서는 반드시 [결제하고 할 상품]이 있어야 한다. 이 때, 우리는 결제가 상품에 의존한다고 한다.
  • 이를 프로그래밍 하려면 [결제] 클래스 내부에는 [상품]이 반드시 있어야 한다.
  • 이 때, [결제] 객체가 스스로 [상품]을 만드는 것이 아니라, 외부에서 결제 객체 내에 상품을 넣어주는 것. 다시 말 해, 주입해주는 것을 의존 주입이라고 한다.
  • 예를 들어, Payment payment = new Payment(productList); 와 같이 생성자를 통해 상품들을 전달해주면 이를 의존 성 주입이라고 한다.

- 의존 주입은 왜 필요할가?

  • 앞의 예시에서, payment의 내부적으로 productList를 사용하기 위해 의존을 주입해주었지만, productList에 수정이 가해져도 payment 내부적으로는 크게 수정하지 않아도 된다.
  • 두 객체를 다르게 설정할 수 있어 코드의 가독성, 재사용성, 테스트 용이성이 좋아진다.

 

- 약한 의존성 주입

  • 그런데, 만일 앞서 설정한 productList의 클래스가 달라지면 어떻게 될까? 당연히 Payment 클래스 내부도 수정해야 한다.
    • private final ProductList productList;  ->  private final PriductListTest producList; 가 된다면?
  • 이렇듯, 의존성이 있는 객체를 외부에서 주입하더라도, 그 외부에서도 직접 객체를 생성하게 되면 많은 수정이 필요하다.
  • 그런데 만약 productList가 interface이고, 이를 구현하는 역할은 다른 무언가가 해준다면 어떨까? productList의 구현체가 뭔지는 알 필요도 없이 payment는 productList의 사용이 가능하다. 
    • private final ProductList productList; 의 ProductList는 interface이기 때문에, 그냥 받으면 된다.
  • 결론적으로, 의존성 주입을 하더라도 의존성 주입의 혜택을  받기 위해서는 클래스 간의 강한 결합을 피하고 느슨한 결합을 해야 한다.
  • 그래서 약한 의존성 주입은 누가 해주는데? 당연히 스프링이 해준다.

 

* AOP

- AOP (Aspect Oriented Programming)란?

  • 한국어로는 관심 지향 프로그래밍이라고 해석할 수 있다.
  • 말 그대로 관심에 따라 프로그래밍을 진행하는 것이다. 개발에서의 관심은 크게 '공통 관심 사항''핵심 관심 사항'으로 나뉜다.
  • 핵심 관심 사항은 흔히 비즈니스 로직으로 알려진 것들이다. 이들은 하나 하나가 핵심적인 기능을 한다.
  • 공통 관심 사항은 로깅이나 보안, 트랜잭션 같이 모든 기능에 공통적으로 적용되는 것들을 의미한다. 사실 해당 기능들이 없더라도 프로그램이 구현되는 데에는 크게 지장이 없기 때문에 부가적인 관심 사항이라고도 불린다.
  • 즉, AOP는 애플리케이션의 핵심적인 비즈니스 로직에서 공통 로을 분리하는 것이다.

- AOP가 필요한 이유

  • 일단 모든 코드에 반복되는 코드가 있다면 코드가 복잡해지고 가독성이 떨어질 것이다. 작성해야 하는 코드도 기하급수적으로 늘어난다.
    • 예를 들어, 로직의 수행 시간을 알아보기 위한 로직을 작성한다고 해보자. 모든 로직마다 시작 시간과 종료 시간을 얻고 이를 출력하는 코드 3줄을 작성하면 간단하다.
    • 문제는 '모든' 로직에 적용돼야 한다는 것이다. 로직의 수가 100개면, 300줄의 코드를 추가로 작성 해야한다.

 

* PSA

- PSA (Portable Service Abstraction)란?

  • 애플리케이션 내부에서 제공되는 서비스를 추상화해서 제공하라는 것이다.
  • 링크에서 예를 든 알림 서비스라고 생각해보자.
    • 서로 다른 알림 서비스 객체를 만들어 운영하면 변화가 유연하지 못하고 유지보수가 어렵다.
    • 하지만 알림 서비스 interface로 추상화를 진행하면 변화에 유연하게 대응할 수 있고 유지보수가 쉽다.

- PSA가 필요한 이유는?

  • 추상화를 하는 이유를 묻는 것과 같다.
  • 개념적으로 추상화가 잘 된 프로그램은 유지보수가 쉽고 변화에 유연하게 대처 가능하다.

 

반응형

댓글