프로그래밍에서 특정 운영 체제를 위한 응용 프로그램 표준 구조를 구현하는 클래스와 라이브러리 모임.
사전적 정의를 해석해보면 FRAME(틀, 규칙)
+ WORK(일, 소프트웨어의 목적)
이며,
즉 어떤 개발이나 소프트웨어든 일종의 규칙이 있고, 그 규칙을 정하는 일이라고 이해하면 된다.
자바로 된 오픈소스 프레임워크로 자바SE로 된 자바 객체(POJO)를 자바EE에 의존적이지 않게 연결해주는 역할.
Bean Factory
, ApplicationContext
라고 불리기도 한다.
자바 개발을 위한 프레임워크로 종속 객체를 생성해주고, 조립해주는 도구이다.
각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있다.
POJO
(Plain Old Java Object) 방식의 프레임워크. 일반적인 J2EE 프레임워크에 비해 구현을 위해 특정한 인터페이스를 구현하거나 상속을 받을 필요가 없이 기존에 존재하는 라이브러리 등을 지원하기에 용이하고 객체가 가볍다.
IoC
, Inversion of Control)을 지원. 컨트롤의 제어권이 사용자가 아니라 프레임워크에 있어서 필요에 따라 스프링에서 사용자의 코드를 호출한다.
(해당 링크를 통해 자세한 설명을 정리했다.)
DI
, Dependency Injection)을 지원각각의 계층이나 서비스들 간에 의존성이 존재할 경우 프레임워크가 DI(의존관계 주입)하여 서로 연결시켜준다.
(해당 링크를 통해 자세한 설명을 정리했다.)
AOP
, Aspect-Oriented Programming)을 지원트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.
(해당 링크를 통해 자세한 설명을 정리했다.)
iBatis나 Hibernate 등 이미 완성도가 높은 데이터베이스 처리 라이브러리와 연결할 수 있는 인터페이스를 제공한다.
스프링 컨테이너(spring container)
는 Bean 생명주기를 관리한다.
BeanFactory 인터페이스
: 스프링 컨테이너의 최상위 인터페이스ApplicationContext 인터페이스
: BeanFactory 인터페이스를 상속받아 Bean을 관리 + 여러가지 부가기능 추가public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
}
ApplicationContext 인터페이스를 보면 여러개의 인터페이스들을 상속받는것을 확인할 수 있다.
public interface ListableBeanFactory extends BeanFactory {
}
그중에서 ListableBeanFactory 인터페이스를 보면 BeanFactory 인터페이스를 상속받는것을 확인할 수 있다.
스프링 컨테이너 생성은 ApplicationContext 인터페이스의 구현체인 AnnotationConfigApplicationContext 클래스를 이용한다.
ApplicationContext ac = new AnnotationConfigApplicationContext();
어플리케이션을 구성하는 Bean들을 관리를 위해 BeanFactory 인터페이스의 구현객체인 IoC컨테이너
(=DI 컨테이너
, 스프링컨테이너
) 를 이용한다.
Spring MVC는 서블릿 컨테이너(웹 컨테이너)
가 관리. 따라서 서블릿 컨테이너가 Spring Bean에 접근하려면 스프링컨테이너(DI컨테이너)를 거쳐야한다
웹 어플리케이션 프레임워크는 HTTP를 통하여 오는 요청을 처리하고, HTTP를 통해 응답을 주는 과정을 제공해주고, Database를 연동할 수 있는 기능을 제공해주는 프레임워크.
<동작 순서>
1) 스프링 MVC 프로젝트를 구동하면 WAS
(Web Server + Servlet Container)가 구동된다.
2) pom.xml
파일내부의 dependency태그들을 통해 필요한 라이브러리를 .m2/repository 폴더안에 다운받는다.
3) web.xml 파일을 로딩하여 서블릿 컨테이너(웹 컨테이너)
구동된다.
이후에 서블릿 컨테이너가 web.xml 파일에 리스너클래스로 명시된 ContextLoaderLisenter
객체를 자동으로 메모리에 생성(pre-loading)한다.
//web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
4) web.xml 파일에서 ContextLoaderListener 클래스가 컨텍스트 파라미터로 등록된 경로에 있는
root-context.xml
파일을 로딩한다. root-context.xml 파일에 등록된 설정에 따라 프로젝트 단위에서 1개만 생기는 최상위 부모 컨테이너인 루트 컨테이너
(스프링컨테이너의 한 종류)를 생성한다. 이때 Service, DAO, VO 등의 객체가 생성된다.
//web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
root-context.xml 파일에 등록된 설정에 따라 프로젝트 단위에서 1개만 생기는 최상위 부모 컨테이너인 루트 컨테이너(스프링컨테이너의 한 종류)를 생성한다. 이때 Service, DAO, VO 등의 객체가 생성된다.
5) 클라이언트의 요청(request)이 오면 서블릿컨테이너가 스프링에서 제공하는 DispatcherServlet
클래스를 이용하는데 DispatcherServlet은 servlet-context.xml
파일의 설정을 토대로 HandlerMapping
에게 해당 요청(request)을 처리할 수 있는 컨트롤러 Bean을 검색하고 DispatcherServlet에게 반환하도록한다.
이후에 DispatcherServlet이 HandlerAdapter
인터페이스에게 HandlerMapping이 찾은 컨트롤러 Bean을 실행시키도록 요청처리를 위임한다.
//web.xml
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
// url-pattern태그의 `/`는 서블릿으로 오는 모든 요청을 매핑해주겠다는 의미.
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
//servlet-context.xml
// @Controller, @RequestMapping 등등 어노테이션으로 이루어진 요청 URI가 매핑된 Handler 클래스를 찾아 요청을 넘김
<annotation-driven />
// css, js, 이미지등을
<resources mapping="/resources/**" location="/resources/" />
// 스캔할 패키지의 범위를 설정
<context:component-scan base-package="com.mycom.myapp" />
6) 컨트롤러가 비지니스 로직을 처리하고 반환된 값을 view에 전달할 객체로 Model
에 저장하고 DispatcherServlet에게 String 타입의 view name
을 반환한다.
DispatcherServlet은 반환된 String타입의 view name을 통해서 ViewResolver
에게 해당 view name이 있는지 확인시키고 /WEB-INF/views 폴더내부에 "view name + .jsp" 로 처리하도록 한다.
//servlet-context.xml
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
참조