기존에 올린 Spring 정리내용을 다시 복습하는 포스팅.
자세한 설명은 아래 링크 참조.
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 1
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 2
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 3
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 4
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 5
2020/05/31 - [🌎Web Application/Spring] - MyBatis 추가 정리
2020/05/31 - [🌎Web Application/Spring] - 💡Spring 동작과정 정리 💡
2020/05/31 - [🌎Web Application/Spring] - 💡용어 정리💡
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 1
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 2
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 3
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 4
2020/05/30 - [🌎Web Application/Spring] - [Spring] MVC Project part 5
2020/05/31 - [🌎Web Application/Spring] - MyBatis 추가 정리
2020/05/31 - [🌎Web Application/Spring] - 💡Spring 동작과정 정리 💡
2020/05/31 - [🌎Web Application/Spring] - 💡용어 정리💡
1. Spring MVC project 생성
new project -> Spring Legacy Project => Next
Templates 설정-> Spring MVC Project 설정 => Next
2. pom.xml 확인
pom.xml
스프링 MVC 개발을 위해 필요한 라이브러리 들을 setting해주는 역할을 한다.
해당 라이브러리 들은 <dependencies>..</dependencies> 태그 사이에 추가해줘야 하며,
추가 후 프로젝트 오른쪽 버튼 Maven->Update Project를 해주어야 라이브러리가 진짜로 추가가 된다.
3. mybatis 관련 라이브러리를 추가(6개: ojdbc/mybatis/mybatis-spring/commons-dbcp/repository)
*ojdbc: oracle driver
*mybatis
*mybatis-spring : spring과 mybatis를 연결해주는 접착제 역할
*commons-dbcp: jdbc의 Database를 사용하기 위함
*spring-orm : 객체의 DB와 Mapping
*repository: ojdbc의 경우 Maven에서 제공하지 않는 라이브러리 이다. 따라서, dependency만 작성해주면 제대로 ojdbc를 다운받지 못한다. repository를 통해 가져와야 한다.
4. pom.xml 에 라이브러리를 추가했으면 Maven->Update project
5. Web.xml 확인 (src/main/webapp/WEB-INF/web.xml)
web.xml
"각종 servlet의 설정과 servlet 매핑, 필터, 인코딩"
(웹 프로젝트의 배치 기술서)웹 애플리케이션의 기본 설정 파일이다.
톰캣이 처음 구동될 때 web.xml을 읽고 그에 해당하는 설정을 구성한다.
= 스프링 프로젝트가 실행되면 가장 먼저 web.xml 을 읽어들이게 되고 위에서 차례로 태그를 해석하기 시작.즉, 톰캣이 처 음 구동될 때 web.xml을 읽는다는 의미 = 톰캣의 환경설정 파일 이라고 생각하면 쉽다.
1. 톰캣의 실행환경에 대한 정보를 담당하는 '환경설정' 파일 이다.
2. 각종 servlet의 설정과 servlet 매핑, 필터, 인코딩 등을 담당한다.
6. root-context.xml->applicationContext.xml & appServlet 폴더로 이동
*contextConfigLocation 파라미터
어떤 객체들을 미리 만들어 놓을지 작성된 설정파일의 경로(applicationContext.xml)를 값으로 할당.
=>왜 contextConfigLocation 파라미터에 applicationContext.xml을 할당하는가?
톰캣이 실행되면 ContextLoaderListener가 contextLoader()를 실행하는데, 그때 contextConfigLocation값을 읽는다.
톰캣이 실행되면 contextConfigLocation값을 읽는다는 의미이다.
생각을 해보자.
톰캣, 즉 WAS, 서버가 처음 구동되면 실행되는 파일이 contextConfigLocation값에 할당된 파일이라는 것이다.
(현재 contextConfigLocation에 할당된 파일은 applicationContext.xml 이다.)
서버가 구동되면 읽는 파일 == 서버가 구동될 때 가장 맨 처음에 읽어져야 할 파일이라는 뜻이다.
그렇다면 그 파일은 어떤 내용이 담겨야 하겟는가.
서버가 구동하는 웹 프로젝트가 필요로 하는 정보가 준비된 파일이면 좋지 않을까?
1. 톰캣이 실행되면 ContextLoaderListener가 contextLoader()메서드를 실행한다.
2. ContextLoaderListener 는 톰캣 구동시에 web.xml을 읽어들여 웹 어플리케이션 설정을 구성하기위해, 초기셋팅작업을 이루어지게 한다.
3. 그리고, contextConfigLocation의 값에 설정된 applicationContext.xml을 읽어들인다.
즉, Context Loader Listener를 통해 applicationContext.xml를 읽어들인다. applicationContext.xml 파일은 어떤 객체들을 미리 만들어 놓을 지 작성된 설정파일 이다.
4. applicationContext.xml 이 읽히고 의존성 해결을 위한 객체들을 생성하게 된다.
.xml
일반적으로 빈 설정 파일은 하나의 파일 만 사용되기 보다는 layer 단위로 나뉘게 된다.
또한, 같은 빈을 2개 이상의 DispatcherServlet이 공통으로 사용할 경우도 있다.
공통 빈 설정 파일은 서블릿 리스너로 등록 된 ContextLoaderListener 로 로딩해서 applicationContext을 만든다.!
(정리)
톰캣이 실행되면 ContextLoaderListner는 web.xml 을 읽고 초기셋팅 작업을 한다.
그 다음, contextLoader()메서드를 실행시키고, 그 메서드는 contextConfigLocation의 값을 읽어들인다. contextConfigLocation에는 applicationContext.xml이 담겨져 있고, aplicationContext.xml에는 어떤 객체들을 미리 만들어 놓을 지 작성된 설정파일이다.
=> 톰캣이 실행되면 applicationContext.xml을 읽어 객체를 미리 생성한다. 빈을 생성한다.=>의존성 해결(DI)
Root WebApplicationContext
ContextLoaderListener를 통해 RootWebApplicationContext를 생성하는데, context-param Element를 통해 선언했끼 때문에 Application 전역에서 사용가능한 WebApplicationContext가 된다.<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
7. " *.do " 로 변경 + Encoding Filter 추가
org.springframework.web.servlet.DispatcherServlet
이하, DispatcherServletSpring MVC Framework 의 유일한 Fornt Controller인 DispatcherServlet은 Spring MVC의 핵심 요소이다.
DispatcherServlet은 Controller로 향하는 모든 웹 요청의 진입점이며, 웹 요청을 처리하며, 결과 데이터를 Client에게 응답한다.
DispatcherServlet은 Spring MVC의 웹 요청 Life Cycle을 주관한다.
<< DispatcherServlet은 앞 단에서 들어온 모든 요청을 받는 Servlet이다. >>
Spring MVC Framework을 사용하기 위해서는 ( 1 ) web.xml에 DispatcherServlet을 설정하고,
DispatcherServlet이 WebApplicationContext를 생성할 수 있도록 ( 2 ) Bean 정보가 있는 파일들도 설정(XXX-context.xml)해주어야 한다.
-Servlet WebApplicationContext
DispatcherServlet을 통해 Servlet WebApplicationContext를 생성하는데, 이는 servlet Element를 통해 선언했기 때문에 해당 Servlet에서만 사용 가능한 WebApplicationContext가 되는 것이다.
<servlet>
<!-- appServlet이라는 웹 애플리케이션의 웹 요청을 DispatcherServlet이 처리한다. -->
<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>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
servlet-name은 DispatcherServlet이 기본(default)으로 참조할 빈 설정 파일 이름의 prefix가 되는데,
(servlet-name)-servlet.xml 같은 형태이다. (DEFAULT)
위의 예제와 같이 web.xml을 작성했다면, DispatcherServlet은 /WEB-INF/spring/appServlet/appservlet-context.xml을 찾게 된다.
만약, 빈 설정파일을 하나 이상 사용하거나, 파일 이름과 경로를 직접 지정해주고 싶다면 contextConfigLocation 이라는 초기화 파라미터 값에 빈 설정 파일 경로를 설정해준다.
webLayer의 빈들은 webApplicationContext에 저장하는 아래와 같은 방법을 사용한다.
web layer의 빈 설정 파일은 DispatcherServlet이 로딩해서 WebApplicationContext을 만든다.
Web Application Context 란?
스프링 어플리케이션에는 application Context는 2개가 들어간다.
- ContextLoaderListener에 의해서 만들어지는 Root WebApplicationContext(in applicationContext.xml)
-DispatcherServlet 에 의해서 만들어지는 WebApplicationContext
1. Root WebApplicationContext
이름 그대로 최 상단에 위치한 Context.
1.1 서비스 계층이나 DAO를 포함한 웹 환경에 독립적인 빈들을 담아둔다.
1.2 Web Application 전체에 사용 가능한 DB연결, 로깅 기능들이 이용된다.
2. WebApplicationContext
서블릿 에서만 이용되는 Context이다.
2.1 DispatcherServlet 이 직접 사용하는 컨트롤러를 포함한 웹 관련 빈을 등록하는 데 사용한다.
2.2 DispatcherServlet은 독자적인 WebApllicationContext를 가지고 있고 모두 동일한 RootWebApplication Context를 공유한다.
Web Applicaton Context VS Apllication Context
스프링에서 말하는 애플리케이션 컨텍스트는 스프링이 관리하는 빈들이 담겨있는 컨테이너라고 생각하면 된다.
스프링 안에는 여러 종류의 애플리케이션 컨텍스트 구현체가 있는데, ApplicationContext라는 인터페이스를 구현한 객체들이 다 이 애플리케이션 컨텍스트 이다. 웹 애플리케이션 컨텍스트는 ApllicationContext를 확장한 WebApplicationContext 인터페이스의 구현체이다. WebAppllicationContext는 ApplicationContext에 getServletContext()메서드가 추가된 인터페이스 이다. 이 메서드를 호출하면 서블릿 컨텍스트를 반환한다. 결국 웹 애플리케이션 컨텍스트는 스프링 애플리케이션 컨텍스트의 변종이면서 서블릿 컨텍스트와 연관관계에 있다는 정도로 정리가 된다.
스프링에서 컨텍스트란 필요한 정보를 포함하고 있는 파일이라고 생각하자.
스프링 에서의 컨텍스트의 계층관계는 흔히 부모-자식 관계로 이루어진다고 한다.
위 그림처럼 서블릿(자식) 컨텍스트가 루트(부모) 컨텍스트를 참조하는 관계이고,
그 반대의 경우는 불가능한 구조이다.
위의 두 WebApplicationContext 선언 코드를 살펴보면 공통적인 부분이 존재한다.
두 컨텍스트 모두 param-name이 contextConfigLocation이라는 것을 볼 수 있는데, 이 부분이 바로 스프링에서 사용되는 컨텍스트 간의 계층 관계를 연결해주는 부분이다.
앞서, context-param Element를 통해 선언한 변수는 전역에서 사용된다고 하였는데,
그렇기 때문에 Application의 전역에는 Root WebApplicationContext이 영향을 미치고 있다.
이때, Servlet에서 Root WebApplicationContext와 같은 param-name의 Servlet WebApplicationContext을
선언하게 된다면, 전역변수와 지역변수의 관계처럼 덮어씌워지는 것이 아닌, 클래스의 상속 관계와 같이 계층 관계로 연결이 되는 것이다.
때문에, 계층 관계로 연결된 Root와 Servlet WebApplicationContext는 Java의 상속관계처럼
Servlet WebApplicationContext에서는 Root WebApplicationContext를 참조 가능하지만,
그 반대는 불가능한 구조로 구현이 가능한 것이다.
명확하게 구분되는 것은 아니지만, 이러한 이유 때문에, 주로 다음과 같이 구성된다.
*Servlet WebApplicationContext
주로 각각의 Servlet에서 사용하는 View 자원을 구성할 때.
DispatcherServlet에서 Root WebApplicationContext를 상속받아 만든 ApplicationContext으로 해당 DispatcherServlet안 에서만 사용이 가능.
1)DispatcherServlet이 직접 사용하는 컨트롤러를 포함한 웹 관련 빈을 등록하는 데 사용한다.
2)DispatcherServlet은 독자적인 WebApplicationContext를 가지고 있고, 모두 동일한 Root WebApplicationContext를 공유한다.
*Root WebApplicationContext
주로 View 자원 이외에 공통적으로 사용이 가능한 Infra, Log 자원 등을 구성할 때.
ContextLoaderListener에 의해 ServletContext에 등록되는 모든 ApplicationContext로 모든 Servlet이 사용 가능.1)서비스 계층이나 DAO를 포함한, 웹 환경에 독립적인 빈들을 담아둔다.
2)서로 다른 서블릿컨텍스트에서 공유해야 하는 빈들을 등록해놓고 사용할 수 있다.
3)Servlet context에 등록된 빈들을 이용 불가능하고
servlet context와 공통된 빈이 있다면 servlet context 빈이 우선된다.
4)WebApplication 전체에 사용가능한 DB연결, 로깅 기능들이 이용된다.
위 그림을 자세히 보면, Root WebApplicationContext에는 모든 Servlet에서 공용으로 사용 가능하게 보이는 Services,Repositories Bean들이 등록되어 있는 것을 볼 수 있다. 때문에, DispatcherServlet이 여러 개가 필요한 Application이 있을 수도 있기 때문에 , Root WebApplicationContext을 DispatcherServlet에서 다시 상속을 받아 필요한 기능을 추가하여 사용하도록 구조를 만들어 두었다고 한다.
*기존의 Serlvet
기존의 방식은 요청 url당 servlet을 생성하고 그에 맞는 Controller를 mapping 후 요청을 보내주는 코드를 각각 따로 작성해야 만 했다.
* Front Controller
Front Controller를 사용하면 하나의 Serlvet에서 모든 요청을 받아들여 적절한 Controller로 요청을 위임한다.
Dispatcher Servlet은 모든 요청을 한 곳에서 받아서 필요한 처리를 한 뒤 요청에 맞는 handler로 요청을 Dispatch하고 해당 Handler 의 실행결과를 Http Response 형태로 만드는 역할을 한다.
8. 모든 요청을 인코딩하기 위해 아래 코드 추가.
<!-- 설정된 값을 encoding하겠다. -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
9. servlet-context.xml 확인
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<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>
<context:component-scan base-package="com.solk.practice" />
base-package에 component-scan을 할 패키지 경로를 명시해주면 해당 경로를 포함한 모든 하위 경로에 적용되고, 애노테이션을 명시한 자바 파일들이 Bean으로 동록 되어 사용 가능해진다.
앞서 Servlet WebApplicationContext에는 주로 View 자원을 구성한다고 하였는데, 쉽게 말해서 Controller에 관한 설정만 한다고 볼 수 있다.
10. MyBatis 설정
2020/05/31 - [🌎Web Application/Spring] - MyBatis 추가 정리
'⚙️Backend > Spring' 카테고리의 다른 글
[Spring] Filter + AOP + Interceptor : AOP (0) | 2020.06.06 |
---|---|
[Spring] Filter + AOP + Interceptor : Filter (2) | 2020.06.06 |
💡용어 정리💡 (0) | 2020.05.31 |
💡Spring 동작과정 정리 💡 (1) | 2020.05.31 |
MyBatis 추가 정리 (0) | 2020.05.31 |