스프링(Spring)

Spring-Data Access, DataSource, Servlet Context, Context 분리와 전략

개발학생 2022. 10. 19. 17:51
반응형

*22년 4월 한 달간 한국이러닝협회의 '실전 개발자를 위한 Spring Framework'를 수강하고 정리한 내용입니다

 

 

1. Spring-Data Access

1) DAO 디자인 패턴

- 비즈니스 서비스와 로우레벨의 데이터 엑세스 작업을 분리
  *위치 순서 -> 비즈니스 레이어(Business Layer), DAO, 데이터베이스(DB)

 

- DAO 레이어: 비즈니스 레이어와 데이터베이스 가운데에 위치, CRUD(Create, Read, Update, Delete) 작업 수행

 

2) 데이터 엑세스 기술 (ORM-Object Relation Mapping)

- JDBC: 자바에서의 관계형 데이터베이스 접속 기술, JDK 레벨에서 지원, 다른 고수준 기술의 기반이 됨

- Spring JDBC: 스프링 자체적으로 지원하는 JDBC Wrapper

- MyBatis: Third-party 자바-관계형DB 매핑 라이브러리, 자바 오브젝트와 SQL문 자동으로 매핑(SQL Mapper)

- JPA: Java ORM 표준 인터페이스

- Hibernate: 자바 ORM 구현체

 

3) Spring-JDBC와 MyBatis

(1) Spring-JDBC

- 스프링 프레임워크에 포함된 공식 데이터베이스 연동 라이브러리

- 유연한 Transaction 처리를 위해 Connection 단의 높은 추상화를 제공함

- Connection-Pool을 지원하고, Result Mapper의 추상화를 사용해 쿼리를 편리하게 수행함

- MyBatis, Hibernate 등이 Spring-JDBC를 사용함

 

(2) MyBatis

- XML을 별도 파일로 분리하고 자바 객체와 SQL 매핑을 지원하는 프레임워크

- 별도의 라이브러리로 존재하고 스프링과 연동모듈을 지원

   -> mybatis-spring 라이브러리 필요

   -> 스칼라 MyBatis, .NET MyBatis 등이 있음 

 

 

2. DataSource

1) DataSource의 역할

- Connection 확보하기 위한 기술: 데이터베이스(DB)에 연결할 수 있음

- 스프링은 DataSource를 통해 Connection을 제공

 

2) DataSource 설정 방법

(1) Connection Pool을 사용하는 방법

- 데이터베이스 커넥션을 미리 여러 개 확보해두고, 클라이언트의 요청에 따라 제공하고 반납받는 시스템

- 매번 물리적으로 커넥션을 생성하지 않기에 성능이 좋아짐

 

(2) DriverManager를 사용하는 방법

- DriverManagerDataSource 클래스 사용

- Connection Pool이나 JNDI를 사용할 수 없는 경우에 사용

 

3) 프로퍼티(Property) 파일을 이용한 설정

(1) 환경에 따라 자주 변경되는 내용의 분리

- 프로퍼티 값으로 제공되는 일부 설정정보(DataSource Bean이 사용하는 데이터베이스 연결정보 등)는

  애플리케이션이 동작하는 환경(개발, 테스트, 스테이징, 운영)에 따라 자주 바뀔 수 있음

- 환경에 따라 자주 변경될 수 있는 내용은 properties 파일로 분리
  -> XML처럼 복잡한 구성을 할 필요가 없고, 키와 값의 쌍(key=value)으로 구성하면 됨

 

(2) 프로퍼티(Property) 파일을 이용한 MySQL 설정 예시

- 프로퍼티 파일로 분리한 정보는 ${ } (프로퍼티 치환자)을 이용하여 설정함

- ${ } 값을 치환해주는 기능은 <context:property-placeholder> 태그에 의해 자동으로 등록되는,
  PropertyPlaceHolderConfigurer Bean이 담당함

 

* database properties 파일

db.driverClass=com.sql.jdbc.Driver
db.url=jdbc:mysql://localhost/testdb
db.username=spring
db.password=book

 

* beans.xml

...


##8번째줄 코드부터
<context:property-placeholder
		location="classpath:config/database.properties"/>

<bean id="dataSource"
		class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        
        <property name="driverClass" value="${db.driverClass}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="$(db.username}" />
        <property name="password" value="${db.password}" />
</bean>

 

 

3. Context 분리와 전략

1) Servlet Context과 Root Context

(1) Servlet Context

- DispatcherServlet
  : 웹의 요청을 최초로 접수, 설정 파일을 이용해서 ServletContext(스프링 컨테이터) 로딩, 여러 개 사용 가능
    -> 자신만의 Context를 생성, 초기화하는 동시에 Root Application Context를 찾아 자신의 부모 Context로 사용

- Spring-MVC와 관련 있는 Bean을 설정

- Servlet에서만 이용되는 Context

- 타 Servlet과 공유하기 위한 Bean들은 Root Application Context에 등록해놓고 사용해야 함

 

(2) Root Context

- Spring-MVC와 분리되어 Bean을 관리하고 싶을 때 사용

- 일반적으로 Servlet context와 Root context 분리하여 운용

 

* Root Context 설정 - web.xml (<context-param>, <listener>부분 주목)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xmlns="http://xmlns.jcp.org/xmL/ns/javaee"
            xsi:schemaLocation="http://xmlns.jcp.org/xmL/ns/javaee"
	<context-param>
    	<param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
    
    <listener>
    	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <servlet>
    	<servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DitpatcherServlet</servlet-class>
        <init-param>
        	<param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>
     </servlet>
     <servlet-mapping>
     	<servlet-name>dispatcherServlet<servlet-name>
        <url-pattern>/</url-pattern>
     <servlet-mapping>
 
 ...

 

2) Spring MVC에서 Context 계층 구조

출처: 한국이러닝협회 '실전 개발자를 위한 Spring Framework'

 

3) Root Application Context

- 전체 계층구조에서 최상단에 위치한 Context

- 서로 다른 Servlet Context에서 공유해야 하는 Bean들을 등록해놓고 사용할 수 있음

- 웹 애플리케이션 전체에 적용 가능한 데이터베이스 연결/로깅기능 등에 이용

- Servlet Context에 등록된 Bean은 이용 불가능

  -> Servlet Context와 동일한 Bean이 있을 경우 Servlet Context Bean이 우선됨

- 하나의 Context에 정의된 AOP 설정은 다른 Context의 Bean은 영향을 미치지 않음

 

4) Context 분리 전략

(1) Servlet Context

- @Controller

<context:component-scan base-package="kr.co.acomp.hello"
									use-default-filters="false">
	<context:include-filter type="annotation"
    		expression="org.springframework.stereotype.Controller" />
</context:component-scan>

 

(2) Root Context

- @Service - 트랜잭션 적용 (with AOP)

 

- @Repository

<context:component-scan base-package="kr.co.acomp.hello"
	<context:include-filter type="annotation"
    		expression="org.springframework.stereotype.Controller" />
</context:component-scan>
반응형