[Spring] Spring 과 SpringBoot의 차이
1. 스프링 (Spring) 이란?
- 엔터프라이즈용 Java 애플리케이션 개발을
편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크
- 스프링이 등장하기 이전에는 비즈니스 로직을 구현하기 위해
기술 자체에 대한 공부를 추가적으로 해야만 했다
비즈니스 로직을 구현하는 기술 자체가
복잡하고 어려웠기 때문에 그렇다
- 스프링은 개발 초기에 기본적인 설정과 적용시킬 기술들만
잘 선택을 해주면 기술보다는 애플리케이션의 로직 자체에
더 집중하여 비즈니스 로직을 구현할 수 있다
- 어떤 개인 및 기업도 스프링을 사용하여 웹 애플리케이션을 개발 할 수 있고
필요하다면 스프링의 코드를 일부 수정하여 사용하여도 무관하다
- 프레임워크는 어떠한 목적을 쉽게 달성할 수 있도록
해당 목적과 관련된 코드의 뼈대를 미리 만들어둔 것을 의미한다
- 애플리케이션 프레임워크는 애플리케이션을 개발하는데 있어
필요한 모든 업무 분야 및 모든 기술과 관련된 코드들의 뼈대를 제공한다
2. 스프링의 특징
1) POJO (Plain Old Java Object) 프로그램을 지향한다
- POJO는 순수 Java만을 통해서 생성한 객체를 의미한다
순수 Java만을 사용한다는 것은 Java 및 Java의 스팩에 정의된
기술만을 사용한다는것을 뜻한다
즉 어떤 객체가 외부 라이브러리나 외부 모듈을 가져와서 사용하면
그 객체는 POJO라고 할 수 없다
- 만약 외부 라이브러리를 import하여 라이브러리의 메서드를 사용하면
사용하던 기술이 Deprecated 되거나 개선된 신기술이 등장하면
기존 기술과 관련된 코드를 모두 고쳐야하는 상황이 발생한다
- POJO를 지키면 외부 기술이나 규약의 변화에 얽매이지 않아
보다 유연하게 변화와 확장에 대처 할 수 있다
객체지향 설계를 제한없이 적용할 수 있고
코드가 단순해져 테스트와 디버깅 또한 쉬워진다
2) IOC / DI (Inversion of Control / Dependency Injection)
(제어의 역전 / 의존성 주입)
- A 인스턴스가 B 인스턴스의 메서드를 호출한다면
A는 B와 의존 관계를 맺은것이다
개발자는 new 키워드로 인스턴스를 생성해서 사용하는데
만약 A가 사용할게 B가 아닌 C라는 인스턴스를 써야한다면
다시 new C 로 만들어줘야하는 수정상황이 발생한다
하지만 이게 A 뿐만아니라 100개 1000개가 있다면
그 많은 코드를 다 수정해주어야한다
- 스프링은 이런 상황을 최소한의 수정만으로 변화를 유연하게 수용할 수 있게 한다
A가 사용하는 메서드를 interface에 추상메서드로 정의한다 (추상화)
그럼 B가 implements 해서 인터페이스를 구현하도록 한다
그리고 A에서 인터페이스 타입의 필드를 선언하고
A의 생성자를 통해 외부로부터 인스턴스를 받아와 인터페이스를 초기화한다(다형성)
그리고는 외부로부터 받아온 인스턴스의 메서드를 호출하면 된다
interface I {
// A가 사용하는 메서드를 인터페이스 I의 추상 메서드로 정의한다 (추상화)
void example();
}
class A {
// 인터페이스 타입의 필드를 선언한다
private I i;
// 생성자를 통해 외부로부터 인스턴스를 받아와 i를 초기화 해준다 (다형성)
public A(I i) {
this.i = i;
}
public void methodOfA() {
// 외부로부터 받아온 인스턴스의 메서드를 호출한다
i.example();
}
}
class B implements I {
// A가 사용하는 메서드를 가진 객체들이 I를 구현하도록 한다
public void example() {
}
}
class C implements I {
public void example() {
}
}
- 위와같은 방법으로 A는 자신이 사용할 객체를 스스로 생성하지 않고
생성자를 통해 외부로부터 받아오고 있다
즉 A는 자신이 사용할 객체를 알지 못하며
그저 i에 할당된 인스턴스에 example()이라는 메서드가 존재한다고만 안다
- 누군가가 A가 사용할 객체를 결정하고 생성해서 A가 인스턴스화 될때
인자로 전달해주어야 한다
그 누군가가 바로 스프링이다
- 개발자가 설정 클래스 파일에 A가 사용할 객체를 C로 설정해두면
애플리케이션이 동작하면서 스프링이 설정 클래스 파일을 해석하고
개발자가 설정해둔대로 C 객체를 생성하여 A의 생성자의 인자로 전달한다
이처럼 개발자가 아닌 스프링이 A가 사용할 객체를 생성하여
의존 관계를 맺어주는것을 IOC (제어의 역전) 라고 한다
그 과정에서 C를 A의 생성자를 통해 주입해주는걸 DI (의존성 주입) 라고 한다
3) AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)
- 애플리케이션을 개발할 때에 구현해야 하는 기능들을
크게 공통 관심 사항 과 핵심 관심 사항으로 분류할 수 있다
핵심 관심 사항은 애플리케이션의 핵심 기능과 관련된 것 들이다
커피 주문 애플리케이션에서는 메뉴 등록하기, 주문하기, 주문변경하기 등등
공통 관심 사항은 모든 핵심 관심 사항에 공통적으로 적용되는 관심 사항들이다
로깅이나 보안 등과 관련된 기능들이 공통적으로 적용되어야 한다
이때 공통 관심 사항들은 관련된 코드가 중복될 수 밖에 없다
이렇게 중복이 되면 수정이 일어나면 모든 중복 코드를 찾아서 수정해줘야한다
이러한 문제를 해결하기 위해 공통 관심 사항과 관련된 기능들을
별도의 객체로 분리해낸 다음에
분리해낸 메서드를 통해 공통 관심 사항을 구현한 코드를 실행 해야한다
이렇게 공통 기능을 비즈니스 로직으로부터 분리해낸 것을
AOP (관점 지향 프로그래밍) 라고 한다
4) PSA (Portable Service Abstraction, 일관된 서비스 추상화)
- 만약 MySQL을 이용해서 개발을 완료했는데
Maria DB로 바꿔야한다고 했을때 전부 수정해야할것 같다
하지만 스프링을 이용하면 동일한 코드로 데이터베이스를 바꿀 수 있다
스프링이 데이터베이스 서비스를 추상화한 인터페이스를 제공해주기 때문이다
이를 JDBC(Java DataBase Connectivity) 라고 한다
각 데이터베이스를 만든 회사들은 자신의 데이터베이스에 접근하는 드라이버를
Java 코드의 형태로 배포를 한다
이 드라이버에 해당하는 Java 코드의 클래스가 JDBC를 구현한다
따라서 JDBC를 기반으로 하여 데이터베이스 접근 코드를 작성 해두면
이후에 데이터베이스를 바꾸어도 기존에 작성한 데이터베이스 접근 로직을
그대로 사용 가능하게 되는것이다
JDBC 처럼 특정 기술과 관련된 서비스를 추상화하여 일관된 방식으로
사용될 수 있도록 한것을 PSA (일관된 서비스 추상화) 라고 한다
3. 스프링 부트 (SpringBoot) 란?
- 스프링은 기존 기술의 복잡성을 크게 줄인 프레임워크지만
그럼에도 불구하고 스프링을 사용하기 위해서는
여러 가지의 사항들을 설정해주어야 한다
하지만 스프링 부트를 사용하면 설정 정보를 간략하게 줄일 수 있다
이유는 스프링부트가 기존의 복잡한 설정을 대신 해주고 있기 때문이다
즉 스프링부트는 스프링으로 애플리케이션을 만들때에
필요한 설정을 간편하게 처리해주는 별도의 프레임워크이다
스프링부트를 사용하면 기존에 어려운 초기 설정에 쏟아야 했을 시간과 노력을
비즈니스 로직을 구현하는데에만 쏟을 수 있는 것이다
이 외에도 기존에는 배포를 할 때에 별도의 외장 웹 서버를 설치하고
프로젝트를 War 파일로 빌드하여 배포를 진행했는데
이러한 방식은 처리 속도가 느리며 번거롭다는 단점이 있었다
반면 스프링부트는 자체적인 웹 서버를 내장하고 있어서
빠르고 간편하게 배포를 진행할 수 있다
또한 스프링 부트를 사용하면 독립적으로 실행 가능한 Jar 파일로
프로젝트를 빌드할 수 있어서 클라우드 서비스 및 도커와 같은
가상화 환경에 빠르게 배포할 수 있다