인터페이스 참조 변수 + @RequiredArgsConstructor

ayboori·2023년 7월 31일
0

Spring

목록 보기
11/24

왜인지 몰라서 찾아 보았다!

내가 궁금했던 코드

interface

public interface CommentService {

	/**
	 * 댓글 생성
	 * @param requestDto 댓글 생성 요청정보
	 * @param user 댓글 생성 요청자
	 * @return 생성된 댓글 정보
	 */
	CommentResponseDto createComment(CommentRequestDto requestDto, User user);

// 기타 메소드 생략...

}

구현한 class

@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);
        
        // 기타 메소드 생략...
    }

호출한 Controller

@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);
    }

인터페이스

참조 1
참조 2

1) 인터페이스는 인스턴스를 못 만든다?

네!
인터페이스를 구현한 타입의 클래스로만 인스턴스를 만들 수 있다.

2) 인터페이스 형식의 변수는 선언할 수 없다?

된다!

인터페이스 형식으로 선언하고 객체 변수를 주입하면 사용은 가능하다.
예를 들어

ControllerService controllerservice = new ControllerImpl();

로 선언 가능하다
이렇게 하면 객체에서 선언한 메소드도 사용 가능하다.

인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지를 저장한다.

@RequiredArgsConstructor

잘 설명된 글이 있어 인용한다!

Spring Framework는 해당 클래스에 Spring Bean을 주입해줍니다.

@Service 어노테이션을 이용하여 YourServiceImpl 클래스는 YourService의 구현체로 스프링어플리케이션의 빈에 등록이 됩니다. 더불어, 스프링의 DI에 의해 YourService에 주입될 때는 해당 인터페이스의 구현체가 주입이 되게 되죠…..

같은 인터페이스의 구현체가 여러개일 경우는 어떻게 해야할까요?

1. 위의 코드와 같이 구현 클래스를 주입 받는 걸로 바꾼다.
2. `@Qualifier` 어노테이션을 이용한다.
3. 스프링 빈의 네임 기반으로 해야한다.

추가로 Qualifier에 대한 도 참조한다.

실무에서는 위와 같이 Service를 인터페이스로 작성하는 방식도 많이 사용하는 것 같다.
나도 이렇게 연습할 거야..!!

profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글