개발 아카이브/Spring

[Spring] @Autowired를 지혜롭게 하는 법.

운클라우드 2021. 10. 21. 23:04
반응형
이 포스팅은 인프런의 김영한 님의 "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술" 강의를 보다가 좋은 내용인 것 같아서 참고하여 포스팅했습니다.

 

Autowired 하는 방법은 아마 대략적으로 3가지가 있을 것입니다.

  1. 그냥 멤버 필드에 @Autowired 하는 방법
  2. 생성자에 @Autowired 하는 방법
  3. Setter에 @Autowired 하는 방법

이 3가지 방법 중, 어떤 방법이 좋은 방법일지, 이번 포스트로 다루어 보겠습니다.

 

시나리오

package com.min.edu.controller;

import com.min.edu.service.MemberService;
import org.springframework.stereotype.Controller;

@Controller
public class MemberController {

    private MemberService memberService;
}

위의 코드처럼 Controller에 memberService라는 서비스 객체를 사용하기 위한 @Autowired를 적용하는 예시입니다.

 

 

 

필드에 @Autowired 하는 방법

@Autowired
private MemberService memberService;

일반적으로 캡슐화에 관심이 없거나, 빠른 생산성을 위해 특별히 신경 쓰지 않는다면 바로 쓰는 방법입니다.

 

memberService가 @Autowired로 묶이면서 스프링이 memberService를 관리합니다.

이제 이 memberService는 사용자에게 노출이 되거나 수정이 되면 안 되는데, 수정이 될 수 있습니다.

⏩ final이 안되기 때문!

 

물론 private라 외부로부터 접근이 불가능하지만, setter나 외부 메서드를 통해서 변경이 가능합니다.

 

 

생성자에 @Autowired 하는 방법

private final MemberService memberService;

@Autowired
public MemberController(MemberService memberService) {
    this.memberService = memberService;
}

가장 추천하는 방법입니다.

 

생성자로 memberService를 처음에 1번만 설정할 수 있습니다.

그 이후 memberService는 final로 선언되어 있기 때문에 외부로부터 수정을 할 수 없습니다.

즉, 캡슐화로 외부로부터 접근과 수정이 불가능합니다.

 

memberService는 스프링을 통해 싱글턴 패턴으로 관리되기 때문에,

외부로부터 접근을 막는 것은 필수이며 위의 코드는 이상적인 코드가 되겠습니다.

 

 

Setter에 @Autowired 하는 방법

private MemberService memberService;

@Autowired
public void setMemberService(MemberService memberService) {
    this.memberService = memberService;
}

첫 번째 방법과 마찬가지로 외부로부터 노출되는 방법입니다.

 

기본적으로 setter를 선언하기 위해 멤버 필드의 final은 선언될 수 없어 memberService는 수정이 될 수 있습니다.

그리고 이미 setter로 인해 외부로부터 노출이 되어 있어서 memberService가 수정이 될 수 있습니다.

 

이러한 방법은 개발자의 실수로 인한 사이드 이펙트가 될 수 있습니다. 그러므로 이 방법은 좋지 않습니다.

 

 

 

결론

생성자에 @Autowired 하는 방법이 가장 좋은 방법입니다.

package com.min.edu.controller;

import com.min.edu.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MemberController {

    private MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

OOP 프로그래밍을 알고 있는 사람들이라면 정말 기본적으로 알고 있는 캡슐화의 개념을 적용일 뿐입니다.

하지만 이러한 가이드가 지켜지지 않는 사람들과 프로젝트가 많이 있습니다.

이 포스트를 보고 다시 한번 돌아보는 것은 어떨까요?

 

 

반응형