*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 계층 구조
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>
'스프링(Spring)' 카테고리의 다른 글
Dynamic SQL (MyBatis 동적 SQL), AOP(Aspect Oriented Programming) (0) | 2022.11.02 |
---|---|
MyBatis 소개, Mapper XML 파일 (0) | 2022.10.27 |
static file 처리와 FileUpload, JUnit & Spring-Test (0) | 2022.10.12 |
@Controller, HTTP 파라미터 처리, RESTful API (2) | 2022.10.05 |
Layered Architecture & @Component, Spring MVC 소개 (0) | 2022.09.27 |