스프링이 무엇인가?
솔직히 매번 찔끔찔끔 공부해서 제대로 정리한적이 없었던 것 같다. 순서는 안맞지만 제대로 정리하고 시작하자
Spring 공식 문서 참조
Spring 위키문서
스프링 프레임워크란
Spring을 사용하면 Java 엔터프라이즈 애플리케이션을 쉽게 만들 수 있도록 종합적인 기능을 제공하는 솔루션이다. 특히 Spring Framework 5.1부터 Spring은 JDK 8+(Java SE 8+)를 필요
특징은 다음과 같다.
- 경랑 컨테이너로써 자바 객체를 직접 관리 (객체의 생성, 소멸 등의 라이프 사이클)
- POJO 방식의 프레임 워크
오래된 방식의 간단한 자바 오브젝트, 자바 언어 사양 외에 어떠한 제한에도 묶이지 않는 자바 오브젝트
- 제어 반전(IoC : Inversion of Control)을 지원
main동작에 필요해서 특정 코드를 호출하는게 아니라 역전으로 해당 코드가 먼저 필요해서 구현해 둔뒤에 main 동작에 필요하다면 해당 구현 메소드를 호출해서 사용한다
- 의존성 주입 (DI : Dependency Injection)
클라이언트가 사용할 서비스를 결정하는것이 아닌, 클라이언트에게 어떤 서비스를 사용할 것인가라고 말하는것이 ‘의존성’, 그리고 그 의존성을 객체로 전달하는 것을 ‘주입’.
이전까지 많이 사용했던 @Autowired를 통한 의존성 주입이 그 예이다. - 관점 지향 프로그래밍(AOP : Aspect-Oriented Programming)을 지원, 트랜잭션이나, 로깅 보안과 같은 공통적으로 사용 하는 기능을 분리하여 관리
그리고 오늘은 가장 중요 모듈중 ApplicationContext(IoC Container)를 정리해 보려고 한다.
ApllicationContext
org.springframework.beans 및 org.springframework.context 패키지는 Spring Framework의 IoC 컨테이너의 기초이며, BeanFactory 인터페이스는 모든 유형을 관리 할 수 있는 기술을 제공한다.
특히 ApplicationConext 는 BeanFactory의 하위 인터페이스로써 다음이 추가 되어있다.
- 위에서 작성한것 처럼 기본적으로 자바 개체를 직접 관리(관계설정, 사용, 제거등의 라이프 사이클)하며
- Spring의 AOP 기능과 쉽게 통합이 가능하고
- 이벤트의 발생과
- 웹 어플리케이션에서 사용하기 위한 WebApplicationContext와 같은 Application-layer 계층의 특정 컨텍스트가 추가되었다.
실질적으로 단순 오브젝트 생성과 관계를 설정하는 BeanFactory에 여러가지 컨테이너 기능을 추가한 것을 ApplicationContext라고 부르며, 이것은 IoC컨테이너(또는 스프링 컨테이너라고도 함)는 ApplicationContext를 구현한 클래스의 오브젝트다.
공식문서 이미지 캡처
이미지에서 볼수 있는것 처럼 IoC 컨테이너를 구현하기 위해선 Metadata
와 POJO
클래스가 필요하다 우선 metadata를 구성해 보려고 한다.
ApplicationContext 구현
토비의 스프링 교재를 참조했습니다.
POJO
위에서 말한것처럼 Plain Old Java Object 의 약자. 단순하게 평범한 자바 오브젝트라고 생각했는데 이와 같은 조건을 충족해야 POJO로 불릴수 있다고 한다.
- 특정 규약에 종속되지 않는다. (비즈니스 컴포넌트나 특정 클래스를 상속하면 안된다)
특정규약을 따라 만들게 하는 경우는 대부분 규약에서 제시하는 특정 클래스를 상속하도록 요구하는 경우가 많으며, 이는 더이상 클래스에 객체지향 설계를 적용하기 어려워지기 때문. - 특정 환경에 종속되지 않는다.
특정 서버나, 특정 기업의 프레임워크 안에서만 동작되는 코드 같은 경우.
그렇다면 장점은 무엇일까?
- 그만큼 깔끔한 코드가 나온다.
- 자동화된 테스트에 매우 유리하다. 환경의 제약은 코드의 테스트를 어렵게 하는데, 어떤 환경에도 종속되지 않는다면 원하는 단계에서 바로 테스트가 가능하다.
- 객체지향 설계를 자유롭게 적용할 수 있다.
METADATA
여기서 나도 잘못생각한게 스프링을 처음 접할 때 xml이 설정파일인가 하고 단정 지은 적이 있었는데, 그것이 아니라 스프링의 메타 정보는 특정한 파일 포맷이나, 형식에 제한되거나 종속되지 않고 BeanDefinition으로 정의되는 스프링의 설정 메타정보의 내용을 표현한 것이 있다면 무엇이든 사용 가능하다.
그렇기때문에 XML, 소스코드 어노테이션, 자바코드, 프로퍼티 파일등 모두 사용 가능하다.
우선 일반적으로 스프링에서는 ApplicationContext를 구현하기위해서 xml에 bean을 등록하여 설정정보를 구현하는 방식을 많이 봤을 것이다.
1 |
|
스프링 3.0버전 이후부터는 가장 선호되는 빈 구성 방식인 자바 기반 구성 방식을 사용 할 수 있다.
일반적으로 @Configuration
클래스에서 @Bean
주석을 달아서 사용한다.
1 |
|
여기서 별개로 빈 의존관계를 주입할 때 Autowired를 많이 사용했다. 그런데 spring framework 4.3부터 바뀐 부분이 있다고 한다. 나중에 따로 정리하자
Spring Framework 4.3부터 @Autowired대상 bean이 시작할 생성자를 하나만 정의한다면 그러한 생성자에 대한 어노테이션은 더 이상 필요하지 않다. 그러나 여러 생성자를 사용할 수 있고 기본/기본 생성자가 없는 @Autowired경우 컨테이너에 사용할 생성자 를 지시하기 위해 생성자 중 하나 이상의 어노테이션을 사용해야한다.
1 |
|
이렇게 생성자 주입을 통하여 메소드를 불러와도 잘된다.
ApplicationContext 종류
처음 IoC 컨테이너를 구성할때 xml로 구성된 파일을 불러올때는 ClassPathXmlApplicationContext를 사용 하였다.
1 |
|
다음은 스프링 3.0 이후부터 도입된 AnnotationConfigApplicationContext를 보자 이 어노테이션은 @Configuration, @Component
로 선언된 것들을 가져올 수 있다.
1 |
|
위 두가지 어노테이션은 현재 웹 어플리케이션에서 가장 많이 쓰이는 ApplicationContext들이다. WebApplicationContext는 ApplicationContext를 확장한 인터페이스이며, 웹 환경에서 사용할 때 필요한 기능이 추가된 애플리케이션 컨텍스트다.
스프링 IoC 컨테이너는 빈 설정 메타정보를 이용해 빈 오브젝트를 만들고 DI 작업을 수행한다.
그리고 이를 사용하려면 특정 빈 오브젝트의 메소드를 호출해서 어플리케이션을 동작시켜야 한다.
이렇게 IoC 컨테이너의 역할은 초기에 빈 오브젝트를 생성하고 DI 한 후에 최초로 어플리케이션을 기동할 빈 하나를 제공하는 역할이다.
그래서 정확히 웹환경에서는 어떻게 동작을 시킬까?
일반적으로 웹환경은 서블릿 컨테이너가 클라이이언트에서 오는 Request를 받아 매핑되어있는 서블릿을 실행해주는 방식으로 동작하는데, 웹 어플리케이션에서 스프링 어플리케이션을 동작 시킬때는 main() 메소드 역할을 하는 서블릿을 만들어 두고, 미리 ApplicationContext를 생성해 둔 다음, 요청이 서블릿으로 들어올 때마다 getBean()으로 필요한 빈을 가져와 정해진 메소드를 실행 한다고 한다.
- 클라이언트 요청이 들어오고,
- 서블릿 컨테이너는 들어오는 요청을 받아서 서블릿을 동작 시킨다.
- 서블릿은 웹 어플리케이션이 시작될 때, 미리 만들어둔 웹 어플리케이션 컨텍스트에게 빈 오브젝트로 구성된 어플리케이션의 동작 역할을 해줄 빈을 요청해서 받는다.
- 그리고 ApplicationContext를 만들고
- 메타정보를 참조하여 초기화 한 후,
- 어플리케이션 동작 책임을 맡은 POJO 빈을 요청하여,
- 메소드를 실행시킨다.
마지막으로 StaticApplicationContext는 코드에 의해 설정 메타정보를 등록하는 기능을 제공하는 컨텍스트다. 테스트용으로 적합하다.
이 컨텍스트를 사용해 앞에서 말한 메타정보 등록방법과 하나의 빈이 다른빈에게 DI되도록 하는 예제를 따라해 보았다.
소스를 따라가보니 ApplicationContext는 그 자체로 IoC와 DI를 위한 빈팩토리라는 것을 테스트소스에서 다시 확인 할 수 있었다.
1 |
|
잘 정리해서 다 외우진 못해도 개념을 꼭 잡아두자.
작성자, DevInSpace