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를 사용하여 데이터를 가져온 후 클라이언트에 반환합니다.
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 메소드를 가지고 있습니다.
package com.example.demo;
import org.springframework.stereotype.Repository;
@Repository
class MyRepository {
public String find() {
return "TEST";
}
}
@Repository
: 데이터에 접근하는 메소드를 가진 클래스에 사용 MyRepository 클래스에는 데이터를 찾는 find 메소드를 통해서 "TEST"문자열을 return 한다.
@Autowired
@Autowired
는 생성자에 적용되어 스프링이 자동으로 필요한 빈을 주입해주는데 사용된다.MyService
와 MyRepository
클래스에 적용되어 있으며, 스프링이 해당 타입의 빈을 찾아 생성자에 자동으로 주입한다.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
스프링 프레임워크에서 @Component
어노테이션은 스프링 IoC 컨테이너에 의해 관리되어야 하는 class
를 나타낸다.
이때 @Controller
, @Service
, @Repository
은 @Component
를 상속 받은 것으로 특정 계층에 대해 특화된 형태이다.
또한 이 어노테이션들은 스프링이 해당 클래스의 객체를 Bean으로 등록하고 의존성을 관리하도록 한다.
1)Component 스캔
스프링은 시작 할 때 @Component
, @Controller
, @Service
, @Repository
등의 어노테이션이 붙은 Class
를 자동으로 스캔해서 Bean을 등록한다.
2) DI (Dependency Injection - 의존성 주입)
@Autowired 어노테이션은 스프링에게 해당 타입의 빈을 주입하도록 요청한다,
특히 스프링 4.3 이후부터는 생성자에 @Autowired 어노테이션을 생략해도 Bean을 주입할 수 있다.