Spring(스프링)
Spring의 정의
- Spring은 자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임 워크
애플리케이션 프레임워크
- 프레임워크는 일반적으로 특정 업무 분야 혹은 한 가지 기술에 특화된 목표를 가지고 만들어짐
- 하지만, 애플리케이션 프레임워크는 애플리케이션 전 영역을 포괄적으로 하는 범용적인 프레임워크
- 개발자가 효율적으로 개발을 진행할 수 있도록 하는 것이 목표
경량급
- 자바 엔터프라이즈 기술의 불필요한 복잡함에 반대되는 개념이며 과도한 엔지니어링을 줄이기 위해 표현
- 톰캣이나 제티에서도 동작하며 기본 개발환경이나 단순 개발툴로도 개발이 가능
오픈소스
- 오픈소스란, 말 그대로 소스가 공개되어 있으며 특별한 라이선스 없이 자유롭게 이용이 가능
- 마음대로 수정이 가능하며, 수정된 제품과 소스를 다시 공개적으로 배포가 가능(단, 원 저작자에 대한 정보등은 표기)
- Spring은 오픈 소스의 취약점인 개개인에 의존적인 문제를 전문 기업을 만들어 지속적으로 개발 가능하도록 하였음
Spring의 목적
엔터프라이즈 개발의 복잡함 해소
- 엔터프라이즈 시스템은 기술적인 제약조건과 요구사항이 늘어나게 되고, 핵심 기능인 비즈니스 로직의 복잡함이 증가해 개발이 복잡해짐
- 위의 두가지는 제거대상이 아니고, 이를 효율적으로 개발하도록 돕는 것이 목적
- Spring은 비침투적인 기술, 즉, 코드의 설계와 구현 방식을 제한하지 않는 방식을 이용
- 이를 통해 기술적인 복잡함과 비즈니스 로직을 다루는 코드가 깔끔하게 분리
기술적 복잡함 해소 방식
- 서비스 추상화
- 기술에 대한 접근 방식이 일관성이 없고, 특정 환경에 종속적인 내용에 대한 해결 방식
- 구현 부분과 기술을 사용하는 인터페이스, 환경과 세부 기술에 독립적인 접근 인터페이스를 제공하는 것을 이용
- AOP
- 기술적인 처리를 담당하는 코드가 성격이 다른 코드에 등장
- 책임에 따라 계층을 구분하고, 기술과 특성에 의존적인 인터페이스나 예외처리 를 최대한 제거해도 근본적인 해결이 되지 않음
- 이를 AOP를 이용해 애플리케이션 로직을 담당하는 코드에 남아 있는 기술관련 코드를 분리
비즈니스와 애플리케이션 로직의 복잡함 해소 방식
- 비즈니스 로직을 담은 코드나 애플리케이션을 담은 코드는 업무에 따라 자주 변경되고 수정됨
- 이로 인해 비즈니스 로직의 상당 부분을 DB에 두는 것이 일반적
- 엔터프라이즈가 커짐에 따라 위의 방식도 위험
- 이에 따라 DB는 단지 데이터를 저장하고 검색과 같은 자체적으로 특화된 기능에만 활용하며 로직을 값싼 애플리케이션으로 이동
- 이를 위해 사용하는 것이 객체지향과 DI(이는 뒤에서 자세히)
POJO 프로그래밍

- 스프링으로 개발한 애플리케이션의 기본 구조를 나타내는 그림
- DI의 기본 아이디어는 유연하게 확장 가능한 오브젝트를 만들고 그 관계를 외부에서 설정
- 주요 기술인 IoC/DI, AOP, PSA(Portable server abstractions)는 애플리케이션을 POJO로 개발할 수 있게 하는 기능 기술
POJO란
- Plain Old Java Object의 줄임말
- 자바의 단순한 오브젝트를 이용해 비즈니스 로직을 구현하는 것을 말함
POJO의 조건
- 특정 규약에 종속되지 않음
- POJO는 자바 언어와 꼭 필요한 API 외에는 종속되지 않음
- 비즈니스 컴포넌트를 만들어야 하는 경우 POJO가 아님
- 즉, 객체지향 설계의 자유로운 적용이 가능한 오브젝
- 특정 환경에 종속되지 않음
- 특정 벤더나 특정 프레임워크에서만 동작 가능해서는 안됨
POJO의 장점
- POJO가 될 수 있는 조건을 만족하는 것이 장점
- 환경과 규약에 영향을 받지 않는 코드는 큰 장점
- 자동화된 테스트에 매우 유리
- 객체지향적인 설계 자유롭게 적용 가능
의존관계 주입(DI)
DI란
- 외부에서 두 객체 간의 관계를 결정해주는 디자인패턴
- 인터페이스를 사이에 두고 의존관계가 고정되지 않도록하며, 런타임 시에 관계를 주입하여 결합도를 낮춤
- 주입 방법으로는 생성자 주입, 필드 주입, 수정자 주입 3가지가 있으며 Spring 4 부터는 생성자 주입이 권장사항
필요한 이유
public class Store {
private Pencil pencil;
public Store() {
this.pencil = new Pencil();
}
}
- 기존의 클래스를 가져와 사용하는 경우 강하게 결합되며, 객체간이 아닌 클래스 간의 관계가 맺어지게 됨
- 상속은 제약이 많고, 확장성이 떨어짐
의존성 주입의 활용
public class Store {
private Product product;
public Store(Product product) {
this.product = product;
}
}
- 외부에서 데이터를 주입받는 방식
- 이를 위해 애플리케이션 실행 시점에 필요한 객체를 생성하고, 의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입
public class BeanFactory {
public void store() {
Product pencil = new Pencil();
Store store = new Store(pencil);
}
}
- 위와 같은 내용을 제어의 역전 (Inversion of Control, IoC)라고 부르기도 함
- 어떤 객체를 사용할 지에 대한 책임이
BeanFactory
클래스에 넘어감
정리
- DI 컨테이너를 통해서 서로 강하게 결합된 클래스를 분리하고, 두 객체 간의 관계를 결정
- 결합도를 낮추고 유연성을 확보하여 테스트 작성에 용이
- 이에 따라, 객체가 계속 생성 소멸이 반복되면 부담이 되고, Spring은 기본적으로 Singleton으로 관리
Singleton이란 최초 한번만 메모리를 할당하고, 그 메모리에 인스턴스를 만들어 사용하는 디자인 패턴
AOP
- 관점 지향 프로그래밍으로 Aspect Oriented Programming의 약자
- 흩어진 Aspect를 모듈화 하는 기법

- 각 흩어진 Aspect들을 모아 모듈화 시킴
프록시 패턴
- 기존 코드를 수정하지 않고 사용이 가능하도록 하는 방식은 프록시 패턴을 활용하기 때문

- 프록시 패턴은 기존 코드 변경없이 접근 제어 또는 부가 기능을 추가
- 인터페이스를 할당 받아 사용할 때, DI를 활용해 구현하는 것으로 활용이 가능
- 하지만 이런 방식도 메소드가 많으면 중복이 많이 발생할 수 있어 사용하는 것이 AOP
주요 개념
- Aspect: 모듈화 시키는 것을 의미
- Advice: 실질적으로 어떤 일을 해야하는 지에 대한 정보
- Pointcut: 어디에 적용해야 하는지에 대한 정보
- Target: Aspect에 적용되는 대상
- Join point: Advice가 적용될 위치, 끼어드는 지점
구현 방법
@Aspect
어노테이션을 사용해 클래스 정의
@Around
를 이용해 Advice 적용 범위 지정
참조