오늘은 그동안 미뤄왔던 Service Layer를 배워보자.
Client – Tomcat – Servlet Filter – DS – Handler Mapper – Handler(@Controller) - (Service Layer) - DAO – Mapper(XML MyBatis) - DB – DAO – Handler – DS – ViewResolver
Service Layer는 어렵진 않지만, 굉장히 번거로운 작업으로 Spring MVC의 기본 구조에서 웹 티어와 비즈니스 로직 사이에 존재한다. 물론 엄밀히 말하면 비즈니스 로직에 포함된다.
우리가 개발하는 프로그램은 크게 Web Tier와 Business Logic으로 구분해서 작업한다. 근데 작업 중에는 양쪽 둘 다 아닌 애매한 작업들이 존재하는데, 이걸 어디에 둬야할까?
Spring MVC는 모든 기능을 굉장히 잘게 잘게 쪼개어 차후 이식성와 유지보수성을 확보한다. 그래서 각 레이어를 굉장히 세분화시켜서 관리한다. 그럼 점에서 두 범위에 들어가지 않는 애매한 작업을 두기 위해 ‘서비스 레이어’를 만든다.
이로 인해 차후 코드 변화가 있을 각 레이어 간의 영향도가 줄어들어, 그 부분만 바꾸도록 한다.
ex ) 파일 업로드, pagination, DAO 인스턴스 생성…
서비스 레이어를 보관할 패키지와 레이어 역할을 할 클래스를 생성한다. 기본적으로 DAO 한 개에 레이어 한 개로 잡는다.
이 역시 인스턴스이기 때문에 톰캣이 스프링 풀을 만들면서 함께 생성되도록 만든다. 그래서 이를 위해 @Repository로 DAO를 관리하듯이 @Service를 붙여 서비스 레이어를 관리한다.
@Service
public class MessagesService {
}
기존에 컨트롤러에서 DAO를 호출했다면, 이제는 서비스가 DAO를 호출에 값을 받고, 그 값을 돌려주는 형태이다. 때문에 @Autowired로 DAO를 DI하여 사용한다.
@Autowired
private MessagesDAO dao;
@Autowired
private FilesDAO fdao;
이제 서비스 레이어에서 DAO를 호출하고 다음과 같이 애매한 작업들을 처리한다.
@Transactional
public void insert(String writer, String content, String title, String realPath, MultipartHttpServletRequest mtfRequest) throws Exception {
// 게시글 처리
BoardDTO dto = new BoardDTO();
dto.setWriter(writer);
dto.setContent(content);
dto.setTitle(title);
int pseq = dao.insert(dto);
// 파일 처리
File realPathFile = new File(realPath);
if(!realPathFile.exists()) {realPathFile.mkdir();}
if(mtfRequest != null) {
List<MultipartFile> fileList = mtfRequest.getFiles("fileList");
for(int i=0; i<fileList.size(); i++) {
MultipartFile multi = fileList.get(i);
String oriName = multi.getOriginalFilename();
String sysName = UUID.randomUUID()+"_"+oriName;
multi.transferTo(new File(realPath+"/"+sysName));
System.out.println("저장된 파일명 : " + oriName );
System.out.println("시스템 파일명 : " + sysName );
FileDTO fDTO = new FileDTO(0, oriName, sysName, pseq);
dao.insertFileData(fDTO);
}
}
}
public int update(String title, String content, String seq) {
int pseq = Integer.parseInt(seq);
BoardDTO dto = new BoardDTO();
dto.setTitle(title);
dto.setContent(content);
dto.setSeq(pseq);
return dao.update(dto);
}