https://tes1194.tistory.com/97
에서 IoC/DI 적용하여 아래처럼 수정해봤습니다!
Controller
@RestController
@RequestMapping("/api")
public class MemoController {
private final MemoService memoService;
public MemoController(MemoService memoService) {
this.memoService = memoService;
}
@PostMapping("/memos")
public ResponseEntity<MemoResponseDto> createMemo(@RequestBody MemoRequestDto requestDto) {
MemoResponseDto memoResponseDto = memoService.createMemo(requestDto);
return ResponseEntity.ok(memoResponseDto);
}
@GetMapping("/memos")
public List<MemoResponseDto> getMemos() {
return memoService.getMemos();
}
@GetMapping("/memos/contexts")
public List<MemoResponseDto> getMemosByKeyword (@RequestParam String keyword) {
return memoService.getMemosByKeyword(keyword);
}
@PutMapping("/memos/{id}")
public Long updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto requestDto) {
return memoService.updateMemo(id, requestDto);
}
@DeleteMapping("/memos/{id}")
public Long deleteMemo(@PathVariable Long id) {
return memoService.deleteMemo(id);
}
}
Service
@Service
public class MemoService {
private final MemoRepository memoRepository;
public MemoService(MemoRepository memoRepository) {
this.memoRepository = memoRepository;
}
public MemoResponseDto createMemo(MemoRequestDto requestDto) {
Memo memo = new Memo(requestDto);
Memo saveMemo = memoRepository.save(memo);
MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
return memoResponseDto;
}
public List<MemoResponseDto> getMemos() {
return memoRepository.findAllByOrderByModifiedAtDesc().stream()
.map(MemoResponseDto::new).toList();
}
public List<MemoResponseDto> getMemosByKeyword(@RequestParam String keyword) {
return memoRepository.findAllByContentsContainsOrderByModifiedAtDesc(keyword).stream()
.map( memo -> new MemoResponseDto(memo))
.toList();
}
@Transactional
public Long updateMemo(Long id, MemoRequestDto requestDto) {
Memo memo = findMemo(id);
memo.update(requestDto);
return id;
}
public Long deleteMemo(Long id) {
Memo memo = findMemo(id);
memoRepository.delete(memo);
return id;
}
private Memo findMemo(Long id) {
return memoRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("선택한 메모는 존재하지 않습니다."));
}
}
Repository
@Repository
public interface MemoRepository extends JpaRepository<Memo, Long> {
List<Memo> findAllByOrderByModifiedAtDesc();
List<Comment> findAllById();
List<Memo> findAllByContentsContainsOrderByModifiedAtDesc(String keyword);
}
Controller의 필드
private final MemoService memoService;
Service의 필드
private final MemoRepository memoRepository;
코드 작성자는 두 필드에 값을 할당해주지 않았습니다.
이 두 변수에 언제 값이 할당되어 아래 코드가 동작 가능한 것일까요??
IoC Container와 Bean
Spring IoC 컨테이너: 'Bean'을 모아둔 컨테이너
빈(Bean): Spring이 관리하는 객체
짜잔~
사실 Spring 프레임워크가 프로그래머를 대신하여 필요한 객체를 생성하고 관리하고 있습니다.
그렇기 때문에 위와 같은 코드도 문제 없이 동작하는 것입니다.
- @Component
- ‘Bean’으로 등록하고자하는 클래스 위에 설정합니다.
- Spring 서버가 뜰 때 위 에노테이션이 있는 클래스를 IoC 컨테이너에 'Bean'을 저장 해줍니다.
- 'Bean' 아이콘 확인 → 스프링 IoC 에서 관리할 'Bean' 클래스라는 표시입니다.
- Spring 'Bean' 이름: 클래스의 앞글자만 소문자로 변경합니다.
public class MemoService → memoServcie - @Component가 설정된 클래스에 대해서 Spring이 해 주는 일 확인하기
// 1. MemoService 객체 생성
MemoService memoService = new MemoService();
// 2. Spring IoC 컨테이너에 Bean (memoService) 저장
// memoService -> Spring IoC 컨테이너
- @ComponentScan
- Spring 서버가 뜰 때 @ComponentScan에 설정해 준 packages 위치와 하위 packages 들을 전부 확인하여 @Component가 설정된 클래스들을 ‘Bean’으로 등록 해줍니다.
- @SpringBootApplication에 의해 default 설정 되어있습니다.
- 3 Layer Annotation
- Spring 3 Layer Annotation은 Controller, Service, Repository의 역할로 구분된 클래스들을 ‘Bean’으로 등록할 때 해당 ‘Bean’ 클래스의 역할을 명시하기 위해 사용됩니다.
- @Controller, @RestController
- @Service
- @Repository
- Spring 3 Layer Annotation은 Controller, Service, Repository의 역할로 구분된 클래스들을 ‘Bean’으로 등록할 때 해당 ‘Bean’ 클래스의 역할을 명시하기 위해 사용됩니다.
'Spring > 팀스파르타' 카테고리의 다른 글
18. 영속성 컨텍스트(Persistance Context)와 트랜잭션(Transaction) (1) | 2024.11.02 |
---|---|
17. JPA란 무엇일까? Entity란 무엇일까? (1) | 2024.11.01 |
15. IoC와 DI (1) | 2024.10.30 |
14. 3 Layer Architecture (1) | 2024.10.28 |
13. JDBC란 무엇일까? (0) | 2024.10.28 |