대부분의 규모가 있는 스프링부트에서는 컨트롤러에서 리포지터리를 직접 호출하지 않고 중간에 서비스를 두어 데이터를 처리한다. 서비스는 스프링에서 데이터를 처리하기 위해 작성하는 클래스이다.

 

서비스가 필요한 이유

 

1. 모듈화

 

어떠한 컨트롤러에서 여러개의 리포지터리를 사용하여 데이터를 조회한 후 가공하여 리턴한다고 가정했을 때, 이러한 기능을 서비스로 만들어 두면 컨트롤러에서는 해당 서비스를 호출하여 사용하면 된다. 만약 서비스로 만들지 않고 컨트롤러에서 구현하려 한다면 해당 기능을 필요로 하는 모든 컨트롤러가 동일한 기능을 중복으로 구현해야 한다.

 

서비스는 모듈화를 위해서 필요하다.

 

2. 보안

 

컨트롤러는 리포지터리 없이 서비스를 통해서만 데이터베이스에 접근하도록 구현하는 것이 보안상 안전하다.

해킹을 통해 컨트롤러를 제어하게 되더라도 리포지터리에는 직접 접근할 수 없기 떄문이다.

 

3. 엔티티 객체와 DTO 객체의 변환

 

엔티티 클래스는 데이터베이스의 직접 맞닿아 있는 클래스로 컨트롤러나 타임리프 같은 템플릿 엔진에 전달하여 사용하는 것은 좋지 않다. 컨트롤러나 타임리프에서 사용하는 데이터 객체는 속성을 변경하여 비즈니스적인 요구를 처리해야 하는 경우가 많은데 엔티티를 직접 사용하여 속성을 변경한다면 테이블 컬럼이 변경되어 엉망이 될수도 있기 떄문이다.

 

그렇기 때문에 엔티티를 대신할 DTO (Data Transfer Object)클래스가 필요하다. 그리고 엔티티 객체를 DTO객체로 변환하는 작업도 필요하다. 이러한 변환 작업은 서비스에서 처리한다.

 

서비스는 컨트롤러의 리포지터리의 중간자적인 입장에서 엔티티 객체와 DTO객체를 서로 변환하여 양방향에 전달하는 역할을 한다.

 

이 강의(점프 투 스프링부트)에서는 DTO를 만들지 않고 엔티티 객체를 컨트롤러와 타임리프에서 그대로 사용하고 있다.
하지만 실제 업무 프로그램을 작성할 때는 엔티티 클래스를 대신할 DTO 클래스를 만들어 사용하기를 권장한다.
DTO클래스에 대해서는 따로 포스팅 하겠다.

 

QuestionService.java

(경로 : /ssh/src/main/java/com/myspringboot/ssh/question/QuestionService.java)

package com.myspringboot.ssh.question;

import java.util.List;

import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
/*
* 스프링의 서비스로 만들기 위해서는 위와 같이 클래스명 위에 @Service 애너테이션을 붙이면 된다.
* @Controller, @Entity 등과 마찬가지로 
* 스프링부트는 @Service 애너테이션이 붙은 클래스는 서비스로 인식한다.
*/
public class QuestionService {
	
    // questionRepository 객체는 생성자 방식으로 DI 규칙에 의해 주입된다.
	private final QuestionRepository questionRepository;
	
	public List<Question> getList(){
		return this.questionRepository.findAll();
	}
	

}

 

QuestionContoroller.java

package com.myspringboot.ssh.question;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Controller
public class QuestionController {

	// private final QuestionRepository questionRepository;
	private final QuestionService questionService;
	
    @RequestMapping("/question/list")
    public String list(Model model) {
    	
    	//List<Question> questionList = questionRepository.findAll();
    	List<Question> questionList = this.questionService.getList();
    	model.addAttribute("questionList", questionList);
    	
        return "question_list";
    }
}

 

실행결과

 

+ Recent posts