Spring/팀스파르타

16. IoC/DI 적용하기 + IoC Container와 Bean

열심히 해 2024. 10. 31. 19:11

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’ 클래스의 역할을 명시하기 위해 사용됩니다.
      1. @Controller, @RestController
      2. @Service
      3. @Repository