[개념 콕] 스프링 빈

내일배움캠프 수료생이 개발에 꼭 필요한 핵심 개념만 콕 집어 드립니다.
May 31, 2024
[개념 콕] 스프링 빈
✍🏼
개발을 시작하시는 여러분, 정보가 너무 많고 배워야 할 것도 산더미라 어디서부터 시작해야 할지 막막하신가요? 내일배움캠프 수료생들이 4개월 동안 배운 엄선된 핵심 개념을 직접 정리해서 알려 드립니다. 공부하다 막히거나 헷갈리는 개념이 있다면 개념 콕으로 정리해보세요.

스프링빈(Spring Bean)이란?

Spring Bean은 Spring IoC(Inversion of Control) 컨테이너에 의해 생성되고 관리되는 자바 객체를 말합니다. Spring Bean은 애플리케이션의 핵심을 이루는 객체입니다.
왜 스프링 컨테이너가 자바 객체를 관리할까요?
 

IoC(Inversion of Control) - 제어의 역전

IoC(Inversion of Control)는 스프링의 특징 중 하나로 객체의 생성과 관리를 개발자가 직접 하는 것이 아니라 스프링 컨테이너가 대신 해주는 것을 말합니다. 쉽게 설명하면 제어를 하던 주체가 바뀌었단 소리입니다. 어떤 것을 제어하고 그것을 제어하는 주체는 무엇일까요? 전통적인 프로그래밍에서는 객체를 생성하고 의존성을 관리하는 작업을 개발자가 직접 수행해야 했습니다. 하지만 IoC 패턴을 적용하면, 객체의 생성과 의존성 관리를 스프링 컨테이너가 대신 처리해줍니다. 이를 "제어의 역전"이라고 부르는 이유는 개발자가 직접 제어하던 객체의 생명주기와 의존성 관리를 스프링 컨테이너에게 위임하기 때문입니다. 즉 우리가 작성한 코드의 변경없이 기능을 확장하고 쉽게 부품을 교체하듯이 개발할 수 있습니다.
 

스프링 컨테이너에 등록하는 방법

우리가 만든 자바 객체가 스프링 컨테이너가 관리할 수 있도록 등록해야겠죠? 빈으로 등록하는 방법에는 크게 자동과 수동 빈 등록 방법이 있습니다.
 

수동 빈 등록

@Configuration 주석이 있는 class에 @Bean 어노테이션을 사용하여 수동으로 등록할 수 있습니다.
@Configuration public class AppConfig { @Bean public UserService userService() { return new UserServiceImpl(userRepository()); } @Bean public UserRepository userRepository() { return new newUserRepository(); } }
 

자동 빈 등록

자동으로 빈을 등록하는 방법은 내가 만든 자바 클래스에 @Component만 달면 됩니다. 이외에 @Controller 나 @Service 등 @Component와 마찬가지로 자동으로 빈을 등록하게 해주는 어노테이션이 있습니다.
@Component public class UserService { ... }
 
이들도 내부를 보면 해당 클래스에 @Component가 적용되어 있어 추가적인 기능이 있는 것이기 때문에 똑같이 자동 빈 등록을 가능하게 해줍니다.
notion image
 

수동 등록 vs 자동 등록, 어떤 것을 사용해야 할까요?

스프링 애플리케이션을 개발할 때, 설정 정보와 실제 동작하는 부분을 분리하는 것이 이상적입니다. 하지만 개발자 입장에서는 빈을 등록할 때마다 @Configuration 설정 클래스에 @Bean 어노테이션을 사용하여 일일이 객체를 생성하고 의존성을 주입하는 과정이 번거로울 수 있습니다. 특히 관리해야 할 빈의 수가 많아질수록 설정 정보가 커지면 관리 부담이 증가합니다.
이러한 이유로 스프링에서는 자동 빈 등록 기능을 제공합니다. @Component 어노테이션이나 그 외 @Controller, @Service, @Repository 등의 어노테이션을 사용하면 해당 클래스를 빈으로 자동 등록할 수 있습니다. 이는 개발자의 편의성을 높여주고 코드의 간결성을 유지할 수 있게 해줍니다.
하지만 모든 상황에서 자동 빈 등록을 사용해야 하는 것은 아닙니다. 애플리케이션 전반에 걸쳐 광범위하게 영향을 미치는 중요한 객체들은 수동으로 빈을 등록하는 것이 유지보수 측면에서 유리할 수 있습니다. 이러한 객체들을 수동으로 등록하면 설정 정보에 명시적으로 나타나게 되므로, 애플리케이션의 구조와 의존성을 한눈에 파악할 수 있습니다.
따라서 자동 빈 등록을 기본으로 사용하되, 수동 빈 등록을 적절히 조합하여 사용하는 것이 좋습니다. 대부분의 경우에는 자동 빈 등록을 사용하여 개발 편의성과 생산성을 높이고, 애플리케이션의 핵심 기술 지원 객체나 중요한 설정 등은 수동 빈 등록을 통해 설정 정보에 바로 나타나게 관리하는 것이 효과적입니다.
 

등록한 스프링 빈을 사용하는 방법

등록한 스프링 빈을 사용하려면 사용할 클래스에서 의존관계를 등록시켜주면 됩니다. 이 의존 관계를 등록하는 방법은 아래와 같이 4가지 방법이 있습니다.
  • 생성자 주입
  • 수정자 주입(setter 주입)
  • 필드 주입
  • 일반 메서드 주입
위 4가지 방법 중에 생성자 주입을 사용하는 것이 좋습니다. 그 이유는 아래와 같습니다.
 

생성자 주입을 사용해야 하는 이유 1. 불변

  • 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없습니다. → 불변하게 설계해야 합니다.
  • 수정자 주입을 사용하려면, setXxx 메서드를 public으로 열어두어야 하고 setter 사용은 지양해야 합니다.
  • 누군가 실수로 변경할 수도 있고, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아닙니다.
 

생성자 주입을 사용해야 하는 이유 2. 누락

프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우에 다음과 같이 수정자 의존관계인 경우, @Aurowired 가 프레임워크 안에서 동작할 때는 의존관계가 없으면 오류가 발생하지만, 지금은 프레임워크없이 순수한 자바 코드로만 단위 테스트를 수행하고 있습니다.
public class OrderServiceImpl implements OrderService { private MemberRepository memberRepository; private DiscountPolicy discountPolicy; @Autowired public void setMemberRepository(MemberRepository memberRepository) { this.memberRepository = memberRepository; } @Autowired public void setDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; }
 
다음과 같이 테스트를 실행하면 Null Point Exception이 발생하는데, memberRepository, discountPolicy 모두 의존관계 주입이 누락되었기 때문입니다.
@Test void createOrder() { OrderServiceImpl orderService = new OrderServiceImpl(); orderService.createOrder(1L, "itemA", 10000); }
 

생성자 주입을 사용해야 하는 이유 3. final 키워드 사용 가능

생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있습니다. 그래서 생성자에서 혹시라도 값이 설정되지 않은 오류를 컴파일 시점에 막아줍니다.
아래 코드를 보면 생성자에서 discountPolicy의 값을 초기화해야 하는데 누락되었습니다. 자바는 컴파일 시점에 java: variable discountPolicy might not have been initialized 와 같은 오류를 발생시킵니다.
@Component public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; }
 
참고: 수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final 키워드를 사용할 수 없습니다. 오직 생성자 주입 방식만 final 키워드를 사용할 수 있습니다.
 
 

내일배움캠프는 개발에 필요한 핵심만 배웁니다

지금까지 꼭 필요한 개발 지식에 대해 알아보았습니다. 내일배움캠프에서는 전문가들이 선별한 핵심 개발 지식으로 개발 공부도, 취업도 보다 효율적으로 할 수 있는데요. 국내 유수의 IT기업 출신 튜터님들과 실습 위주의 독보적인 커리큘럼으로 개발자 취업을 체계적으로 준비해보세요. 내일배움캠프 4개월, 여러분 인생의 가장 큰 터닝 포인트입니다.
 
 
 
CREDIT
글 | 손창현 내일배움캠프 수료생 편집 | 정효재 팀스파르타 에디터
 
 

취업 준비, 어디서부터 시작해야 할지 모르겠다면?

 
🧐비전공자인데 IT 업계 취업할 수 있을까?
😟프로젝트 경험이 부족한데, 어떻게 준비해야 할까?
🥺IT 기업으로 이직하고 싶은데 뭐부터 시작해야 할까?
 
이런 고민을 하고 있다면, 내일배움캠프의 IT 취업 컨설팅을 받아보세요.
취업 코칭 전문가들이 여러분의 고민을 해결해 드립니다.
 
다음 링크에 이메일을 입력하시면 메일로 1:1 커리어 상담권과 취준 자료집을 보내드릴게요.
 
 
 
Share article
Subscribe to our newsletter

내일배움캠프 블로그