개요
우리나라에서는 웹프로젝트를 개발할때 거의 대부분을 Spring Framework를 사용하여 개발을 진행하는것 으로 알고 있습니다.
그래서 Spring의 생명주기와 어떤식으로 로직을 처리하고 데이터를 처리하는지 알아보도록 하겠습니다.
Spring LifeCycle (생명주기) 흐름도
Spring에서는 개발자가 직접 구현을 해줘야하는 부분도 있고, Spring 에서 자체적으로 지원해주는 부분도 있습니다.
이해하기 쉽게 각각 나누어서 알아보도록 하겠습니다.
개발자 구현 Life Cycle
(Controller -> Service -> DAO -> DB -> DAO -> Service -> Controller)
Spring Framework에서 자체적으로 지원하는 Life Cycle
Spring Life Cycle 명칭 설명.
- Filter
- Web Application의 전역적인 로직을 담당.
- Fliter라는 단어 뜻에서 알 수 있듯이, 전체적인 필터링(설정)을 하는 곳.
- DistpatcherServlet에 들어가기 전인 Web Application단에서 실행됨.
- DispatcherServlet
- 들어오는 모든 Request를 우선적으로 받아 처리해주는 서블릿.
- HandlerMapping에게 Request에 대해 Mapping할 Controller 검색을 요청.
- HandlerMapping으로부터 Controller 정보를 반환받아 해당 Controller와 매핑시킨다.
- Request에 대해 어느 Controller로 Mapping 시킬 것인지 배치하는 역할을 한다.
- HandlerMapping
- DispatcherServlt으로부터 검색을 요청받은 Controller를 찾아 정보를 Return 해줌.
- HandlerInterceptor
- Request가 Controller에 Mapping되기전 앞단에서 부가적인 로직을 추가할 수 있다.
- 주로 세션, 쿠키, 권한 인증 로직에 많이 사용됨.
- Controller
- Request와 Mapping되는곳.
- Request에 대해 어떤 로직(Service)으로 처리할 것인지를 결정하고, 그에 맞는 Service를 호출함.
- Service Bean의 메소드를 호출해야 하기 때문에 Service Bean을 스프링 컨테이너로부터 주입받아야 함.
- Repository (DAO)
- DB에 접근하는 객체. DAO(Data Access Object) 라고 부른다.
- Service에서 DB에 접근할 수 있게 하여 데이터의 CRUD를 할 수 있게 해줌.
- ViewResolver
- Controller에서 Return한 View의 이름을 DispatcherServlet으로부터 넘겨받고, 해당 View를 랜더링한다.
- 랜더링한 View는 DispatcherServlet으로 Return하고, DispatcherServlet에서 해당 View 화면을 Response한다.
- DB
- Repository (DAO)가 직접 접근하는 데이터 저장소
- CRUD를 수행하고 결과를 DAO에 반환함.
Spring Life Cycle 동작 설명
Spring life cycle에 따르면 클라이언트가 Request 요청을 할 때 DispatcherServlet이 요청을 가로 채게 됩니다.
그러나 이때 모든 요청을 가로채는 것이 아니라 Web.xml에 <url-pattern>에 등록된 내용만 가로채게 됩니다.
그래서 보통 Web.xml 의 <url-pattern> 을 확인하게 되면...
Web.xml -> Servlet-mapping -> url-pattern -> /servlet/TestUploadServlet
Web.xml -> Servlet-mapping -> url-pattern -> /servlet/TestDownloadServlet
Web.xml -> Servlet-mapping -> url-pattern -> /servlet/TestExportServlet
등등 사용자가 임의로 만들어서 설정을 해줄 수 있습니다.
DispatcherServlet이 가로챈 요청은 위와 같이 3개인데 (사용자마다 다름) 이 것을 HandlerMapping에게 보내 요청을 처리할 수 있는 Controller를 찾습니다.
즉 클라이언트가 요청한 url이 위와 같다면 Controller로 넘어가게 됩니다.
개발자 구현 Life Cycle 코드
위에서 본것과 같이 개발자가 구현해야 하는 부분은 총 5개 입니다.
- Web Browser 에서 특정 URL을 통해 Controller 호출. (.html, .js 파일 생성.)
- Controller 생성. (GetMapping 과 PostMapping을 통해 호출받은 URL을 통해 Mapping)
- Service 생성. (보통 Service는 Interface로 생성하고 따로 구현체를 만들어줌.)
- DAO 생성. (DB에 접근하는 DAO객체를 생성.)
- DB 작성. (Spring에서는 보통 Mybatis를 이용하여 DB와 Mapping 시킴.)
간단히 버튼을 눌러 Insert 하는 부분의 구현
1. Web Browser 에서 특정 URL을 통해 Controller 호출.
<div>
<h2>게시물리스트</h2>
.
.
.
.
<table>
<tr id="brdRmkArea">
<th ><label>내용</label></th>
<td colspan="3" style="height:390px;">
<textarea name="TEST_CONTENT" id="TEST_CONTENT" title="내용" placeholder="내용"></textarea>
</td>
</tr>
<tr>
<th><label class="is-required">제목</label></th>
<td>
<input type="text" name="TEST_TIT" id="TEST_TIT" style="" value="" title="제목" placeholder="제목" maxlength="100" />
</td>
</tr>
<tr>
<button type="button" id="btnCustom">신규</button>
</tr>
</table?
</div>
해당 id 값을 통해 js 파일 값 Mapping 및 Ajax POST 통신으로 호출함.
$("#btnCustom").click(function(e){processRtn();});
processRtn:function() {
var objJsonParms = new TestJSON();
objJsonParms.setData("USER_ID", Seesion.getUserID());
objJsonParms.setData("TEST_CONTENT", $("#TEST_CONTENT").valExt());
objJsonParms.setData("TEST_TIT", $("#TEST_TIT").valExt());
var strURL = "/api/test/upload";
$.ajax({
type:"POST",
url : strURL,
data : ("Json 형식의 값") //각자 상황에 맞게 사용
dataType: "json",
async: false,
success:function(obj) {
.
.
. // 상황에 맞는 JSON 객체 대입
}
}
2. Controller 생성
- PostMapping 방식을 이용하여 Web Brower 에서 호출한 URL과 Mapping
- js 파일에서 JSON 파일을 자체적으로 Custom 할 수 있기때문에 파라메터로 json을 받는다.
- TestJSON이라는 데이터 전송객체를 따로 만들어서 사용함.
@Slf4j
@RequiredArgsConstructor
@RestController
@Api(value = "TestRestController")
public class TestRestController
{
private final TestService testService
@ApiOperation(value = "테스트-데이터-삽입")
@PostMapping("/api/test/upload")
public Object Test_insert(TsetJSON tjson) throws Exception
{
TestJSON ojson = new TestJSON(tjson); // 반환파라메터
TestJSON pjson = new TestJSON(pjson); // 전송된 파라메터 변환
ojson = testService.Testinsert(pjson);
retrun ojson;
}
}
3. Service Interface 생성
Service 를 왜 Interface로 생성하는지는 따로 정리함.
public interface TestService
{
TestJson Testinsert(TestJSON pjson) throws Exception
}
https://jung-story.tistory.com/129
4. Service 구현
- Service에서는 DAO를 호출하여 DB에 접근합니다.
- @Transactional(readOnly = false) 인 이유는 insert into 문을 사용하기 때문에 트랙잭션 처리를 해주는 부분입니다.
@Slf4j
@RequiredArgsConstructor
@Service("TestService")
public class TestServiceImpl implements TestService
{
private final TestDAO tdao;
@override
@Transactional(readOnly = false)
public TestJson Testinsert(TestJson pjson) throws Exception {
return tdao.insert("mapping 될 xml파일과의 namespace값", "xml의 id 값", pjson);
}
}
5. DAO구현
- JSON 객체를 통해 전달하기 때문에 HashMap을 사용합니다.
@Slf4j
@Repository
@Transactional
public class TestDAO
{
public TestJSON insert(String sqlNamespace, Sting sqlid, TestJSON tjson) throws Exception
{
private SqlSession testsqlSession;
TestJSON objJson = new TestJSON(tjson);
HashMap<String, String> map = new HashMap<>();
Gson gson = new Gson();
map = gson.fromJson(json, map.getClass());
testsqlSession.insert(sqlNamespace+sqlid,map);
}
}
6. xml파일 작성. (Oracle12 기준)
- js파일에서 Json을 통해 셋팅한 Data를 DB 칼럼값에 Mapping시켜 sql문을 수행합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="service부분의 첫번째 파라메타와 값일치">
<insert id=service부분의 두번째 파라메타와 값일치 parameterType="java.util.HashMap">
INSERT INTO TEST_TABLE
(TEST_TIT
,TEST_CONTENT
,TEST_USER
)
VALUES
(#{TEST_TIT}
,#{TEST_CONTENT}
,#{TEST_USER}
)
</insert>
</mapper>
결론
- 이렇게 하면 최종적으로 Web Browser에서 Controller를 호출하고 Controller는 다시 Service를 호출하며,
- Service는 DAO를 호출하여 mybatis를 통해 xml과의 Mapping을 하여 원하는 쿼리문을 수행하고 다시 반대로 쭉 반환되어 Web Browser에 뿌려지는 모습을 확인 할 수 있습니다.
'서버 > Spring' 카테고리의 다른 글
[Spring] 외부 API 연동 (Java REST API방식과 Ajax 방식) 코드 및 설명 (0) | 2021.09.28 |
---|---|
[Spring] - Service를 Interface로 생성 하는 이유. (AOP, 결합도) (2) | 2021.08.11 |
[Spring] Mybatis (Interface생성 및 xml 파일과 Mapping) (1) | 2021.08.03 |
[Spring] 자바 ORM 표준 JPA 란? (0) | 2021.07.27 |
[Spring] Spring boot 내장 서버 (Tomcat , Undertow) 및 서블릿, 서블릿컨테이너 (0) | 2021.07.16 |