
왜인지 몰라서 찾아 보았다!
public interface CommentService {
/**
* 댓글 생성
* @param requestDto 댓글 생성 요청정보
* @param user 댓글 생성 요청자
* @return 생성된 댓글 정보
*/
CommentResponseDto createComment(CommentRequestDto requestDto, User user);
// 기타 메소드 생략...
}
@Service
@RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {
private final PostServiceImpl postService;
private final CommentRepository commentRepository;
private final CommentLikeRepository commentLikeRepository;
@Override
public CommentResponseDto createComment(CommentRequestDto requestDto, User user) {
Post post = postService.findPost(requestDto.getPostId());
Comment comment = new Comment(requestDto.getBody());
comment.setUser(user);
comment.setPost(post);
var savedComment = commentRepository.save(comment);
return new CommentResponseDto(savedComment);
// 기타 메소드 생략...
}
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CommentController {
private final CommentService commentService;
@PostMapping("/comments")
public ResponseEntity<CommentResponseDto> createComment(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody CommentRequestDto requestDto) {
CommentResponseDto result = commentService.createComment(requestDto, userDetails.getUser());
return ResponseEntity.status(HttpStatus.CREATED).body(result);
}
네!
인터페이스를 구현한 타입의 클래스로만 인스턴스를 만들 수 있다.
된다!
인터페이스 형식으로 선언하고 객체 변수를 주입하면 사용은 가능하다.
예를 들어
ControllerService controllerservice = new ControllerImpl();
로 선언 가능하다
이렇게 하면 객체에서 선언한 메소드도 사용 가능하다.
인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지를 저장한다.

잘 설명된 글이 있어 인용한다!
Spring Framework는 해당 클래스에 Spring Bean을 주입해줍니다.
@Service 어노테이션을 이용하여 YourServiceImpl 클래스는 YourService의 구현체로 스프링어플리케이션의 빈에 등록이 됩니다. 더불어, 스프링의 DI에 의해 YourService에 주입될 때는 해당 인터페이스의 구현체가 주입이 되게 되죠…..
같은 인터페이스의 구현체가 여러개일 경우는 어떻게 해야할까요?
1. 위의 코드와 같이 구현 클래스를 주입 받는 걸로 바꾼다.
2. `@Qualifier` 어노테이션을 이용한다.
3. 스프링 빈의 네임 기반으로 해야한다.
추가로 Qualifier에 대한 글도 참조한다.
실무에서는 위와 같이 Service를 인터페이스로 작성하는 방식도 많이 사용하는 것 같다.
나도 이렇게 연습할 거야..!!