DI를 활용한 Controller, Service, Repository 흐름 구현

Dami·2023년 11월 4일
0

SPRING

목록 보기
6/14
post-thumbnail

스프링 3계층 구현하기

Controller

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.stereotype.Controller;

@Controller
public class MyController {
    @Autowired
    private final MyService service;

    public MyController(MyService service) {
        this.service = service;
    }

    @GetMapping("/test")
    @ResponseBody
    public String getData() {
        return service.findData();
    }
}

@Controller: HTTP 요청을 처리하는 메소드를 가진 클래스에 사용
MyController는 HTTP GET 요청(/data)을 처리하고 MyService를 사용하여 데이터를 가져온 후 클라이언트에 반환합니다.

Service

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private final MyRepository repository;

    public MyService(MyRepository repository){
        this.repository = repository;
    }

    public String findData(){
        return repository.find();
    }
}

@Service: 비즈니스 로직을 처리하는 클래스에 사용
MyService 클래스는 MyRepository를 통해 데이터를 가져오는 findData 메소드를 가지고 있습니다.

Repository

package com.example.demo;

import org.springframework.stereotype.Repository;

@Repository
class MyRepository {
    public String find() {
        return "TEST";
    }
}

@Repository: 데이터에 접근하는 메소드를 가진 클래스에 사용 MyRepository 클래스에는 데이터를 찾는 find 메소드를 통해서 "TEST"문자열을 return 한다.

DI를 활용한 흐름

  • @Autowired
    @Autowired는 생성자에 적용되어 스프링이 자동으로 필요한 빈을 주입해주는데 사용된다.
    위 코드에선 MyServiceMyRepository 클래스에 적용되어 있으며, 스프링이 해당 타입의 빈을 찾아 생성자에 자동으로 주입한다.

Controller -> Service -> Repository -> Service -> Controller 흐름

1) Controller :
HTTP 요청을 받아들인다. 이 요청을 분석하고 유효성 검사를 수행한 다음, Service 계층에 전달한다.

2) Service :
비즈니스 로직이 구현되어 있는 지점
Controller로부터 받은 데이터에 대한 처리(연산, 조건 분기 등)를 담당한다.

3) Repository :
데이터베이스와의 통신을 담당하는 계층.
Service 계층으로부터 호출을 받아 실제 데이터베이스에 저장하거나 조회하는 작업을 수행
데이터베이스와 관련된 예외를 처리하고, 스프링의 예외로 변환하여 Service 계층에 전달할 수 있다.

위 구현에서는 데이터베이스 대신 "TEST" 문자열을 반환하며, 이를 Service 계층에 전달했다.

4) Service :
데이터를 가져오는 것과 같은 데이터 접근 로직은 Repository 계층이 담당하기 때문에, Service 계층은 순수하게 비즈니스 로직에만 집중할 수 있다.

위 구현에서 Service는 Repository로부터 "TEST" 문자열을 받아 왔다.

5) Controller :
Service 계층으로부터 받은 데이터를 클라이언트에게 전달하기 적합한 형태로 변환하여 반환했다.

의존성 주입

@Autowired 어노테이션이나 생성자 기반 주입을 통해
스프링에서는 이러한 계층 간의 의존성 주입(DI, Dependency Injection)을 자동화하여 각 계층의 인스턴스가 필요한 다른 계층의 인스턴스를 자동으로 받을 수 있게 해준다.

Controller가 Service를 호출
→ 서비스가 Repository를 호출
→ 그 결과를 다시 서비스로 전달
→ 마지막으로 Controller가 그 결과를 Client에게 반환

의 흐름이 완성된다.

정리 : @Component 어노테이션과 스프링이 어떻게 DI(Dependency Injection)를 수행할까?

Spring 에서 @Component

스프링 프레임워크에서 @Component 어노테이션은 스프링 IoC 컨테이너에 의해 관리되어야 하는 class를 나타낸다.
이때 @Controller, @Service, @Repository@Component상속 받은 것으로 특정 계층에 대해 특화된 형태이다.

또한 이 어노테이션들은 스프링이 해당 클래스의 객체를 Bean으로 등록하고 의존성을 관리하도록 한다.

스프링이 DI를 수행하는 과정

1)Component 스캔
스프링은 시작 할 때 @Component, @Controller, @Service, @Repository 등의 어노테이션이 붙은 Class를 자동으로 스캔해서 Bean을 등록한다.

2) DI (Dependency Injection - 의존성 주입)
@Autowired 어노테이션은 스프링에게 해당 타입의 빈을 주입하도록 요청한다,
특히 스프링 4.3 이후부터는 생성자에 @Autowired 어노테이션을 생략해도 Bean을 주입할 수 있다.

0개의 댓글