Spring
- Java Enterprice 개발을 편하게 해주는 Opensource 경량급 Application Framewrok
- DI(Dependency Injection), IoC(Inversion Of Control), AOP(Aspect Oriented Programming)를 지원하는 경량의 컨테이너
- Java 개발을 위한 Framewrok로 종속 개체를 생성해주고, 조립해주는 도구
한마디로 Java로 개발할때 좀 더 편하게 개발할 수 있도록 도와주는 Framework 혹은 기술도구라고 생각하면 된다.
Container
Spring 하면 빠질 수 없는 키워드이다. Container는 자바 객체의 생명주기를 관리하며, 생성된 Java 객체들에게 추가적인 기능을 제공하는 역할을 한다. 여기서 말하는 Java 객체를 Spring에서 Bean이라고 부른다.
Spring Container 종류
BeanFactory
- BeanFactory는 bean을 등록, 생성, 조회하고 돌려주는 등 관리하는 역할을 한다. getBean()메소드를 통해 빈을 인스턴스화 할 수 있다.
- Client로부터 요청이 들어올 때만 객체를 생성한다.
Application Context
- BeanFactory의 객체 생성 및 관리 + 트랜잭션 관리/ 메시지 기반의 다국어처리 지원
- Container가 구동되는 시점에 bean에 등록된 Class를 객체화 한다.
특징
POJO(Plain Old Java Object) 방식
- POJO는 JavaEE를 사용하면서 해당 플랫폼에 종속되어 있는 무거운 객체들을 만드는 것에 반발하여 나타난 용어이다.
- 별도의 프레임워크 없이 JavaEE를 사용할 때에 비해 인터페이스를 직접 구현하거나 상속받을 필요가 없어 기존 라이브러리를 지원하기 용이하고, 객체가 가볍다.
- getter/setter를 가진 단순한 자바 오브젝트를 뜻한다.
DI(Dependency Injection)
- 클래스는 다른 클래스를 자신의 내부에서 직접 생성하여 의존관계를 맺고, 관계를 맺은 클래스의 객체 생성을 제어할 수 있다. 두 객체간의 긴밀한 결합이 생기는 것이다. 그리고 관계를 맺은 클래스의 객체가 변경되면 해당 클래스를 의존하고 있는 클래스의 객체또한 변경될 수 있다. 즉, 하나의 모듈이 바뀌면 의존하고 있는 모듈까지 변경되어야 한다는 것이다.
- 위와 같은 방식은 높은 결합도로 인해 오류대응이나 변경이 번거롭다.
- 스프링은 이와 같은 부분을 해소하기위해 관계를 맺고자하는 클래스를 따로 IoC 컨테이너에 Bean으로 생성하고, 관리한다. 관계를 맺고자한다면 직접 클래스를 생성하는 것이 아니라 외부에서 해당 객체를 필요로 하는 곳에 전달하여 주입시켜주고, 관계를 맺을 수 있게 해준다. 이것을 의존성 주입이라고 표현한다.
- 위와 같은 주입방식을 통해 클래스에서 발생한 일로 인해 다른 클래스에게 영향을 끼치는 상황을 방지할 수 있다. 클래스간의 의존성을 최소화하여 결합도를 낮출 수 있다는 뜻이다.
- 클래스를 직접 생성하는 것이 아닌, 주입해줌으로써 객체 간의 결합도를 줄이고 좀 더 유연한 코드를 작성할 수 있다.
- 하지만 의존 관계를 주입할 객체를 반복적으로 생성하고 소멸한다면 아무리 GC가 성능이 좋아졌다고는 하지만 부담이된다. 그래서 스프링은 Bean들을 기본적으로 싱글톤(Singleton)으로 관리한다.
IoC(Inversion Of Control)
- 위에서 DI에 대한 개념을 설명했는데 이와 같은 구조를 설정은 개발자가 아닌 XML이나 어노테이션을 통한 프레임워크가 제어한다.
- BeanFactory, Application Context 라고 불리는 IoC컨테이너는 POJO의 생성, 초기화, 소멸에 대한 권한을 가진다.
- 이를 당연히 개발자가 아닌 프레임워크(컨테이너)가 관리하게 된다.
- 인터페이스 기반 설계가 가능하고, 컴포넌트 재사용성이 증가한다. 일반적인 클래스 호출 방식은 클래스 내에 선언과 구현이 결합성이 높아 변화가 어렵지만, IoC는 팩토리 패턴의 장점을 통해 결합성이 낮고 실행 시점에 클래스간의 관계가 형성된다. 따라서 효율적인 의존성 관리가 가능하다.
- 위와 같은 개념을 내포한 것이 IoC이다. 프로그램의 제어권이 개발자가 아닌 프레임워크에 있는 것을 말한다.
AOP(Aspect Object Programming)
- 각각의 클래스들은 코드와 기능들이 중복되는 부분이 많은 경우가 존재한다. 코드가 중복될 경우 실용성과 가독성 및 개발 속도에 안좋은 영향을 끼친다. 중복된 코드를 최대한 배제하는 방법은 반복되는 기능들을 따로 분리하여 빼놓은 뒤 필요한곳에서 호출할 때 사용되면 효용성을 높일 수 있다.
- 로깅, 트랜잭션, 보안 등이 대표적이 예시이며, 여러 모듈에서 공통적으로 사용하는 기능들이다.
- AOP는 이렇게 공통적으로 사용되는 기능들을 구분하고, 분리해서 작성한뒤 재사용성을 높여주는 프로그래밍 기법이다.
PSA(Portable Service Abstraction)
- 환경과 변화에 관계없이 일관된 방식의 기술 접근 환경을 제공하려는 추상화 구조를 말한다.
- 외부 라이브러리들을 POJO로 사용할 수 있도록 일종의 껍데기를 씌워 추상화한 것으로, 스프링에서 추상화된 서비스들을 자바언어로 자유롭게 사용할 수 있게된다.
- 예시로 org.mybatis.spring은 mybatis를 스프링에서 POJO로 사용할 수 있게끔 추상화 한 패키지이다.
- Netty, Jetty, Tomcat, Undertow 또한 스프링에서 추상화 하여 사용할 수 있다.
내용 정리
- 경량 Container로서 Java 객체(bean)를 직접 관리한다.
- 각각의 개체 생성, 소멸과 같은 life Cycle(생명주기)을 관리하며, 사용자는 Spring 으로부터 필요한 객체를 얻어온다.
- 일반적인 J2EE Framework에 비해 구현을 위해 특정한 interface를 구현하거나 상속받을 필요가 없어 기존에 존재하는 library 등을 지원하기에 용이하고 객체가 가볍다.
- 제어의 역행(IoC)를 지원한다. 풀어서 설명하자면 컨트롤의 제어권이 사용자가 아니라 프레임워크에 있다는 것을 의미하고, 필요에 따라 Spring 에서 사용자의 코드를 호출한다.
- 의존성 주입(DI)를 지원한다. 풀어서 설명하자면 각각의 계층이나 서비스들간의 의존성이 필요한 경우 Framework가 서로 의존관계를 맺어준다.
- 관점지향프로그래밍(AOP)를 지원한다. 풀어서 설명하자면 트랜잭션, 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.
- Spring은 영속성과 관련된 다양한 서비스를 지원한다. iBatis나 Hibernate 등 이미 완성도가 높은 데이터베이스 처리 library와 연결할 수 있는 interface를 제공해준다.
- Spring은 높은 확장성을 자랑한다. Framework에 통합하기 위해 간단하게 기존 library를 감싸는 정도로 Spring에서 사용이 가능하기 때문에 수많은 library가 이미 Spring에서 지원되고 있고, Spring에서 사용되는 library를 별도로 분리하기 용이하다.