본문 바로가기
Frameworks/Spring

[Spring] Bean

by junseokoo 2025. 4. 11.

Bean

  • 스프링 컨테이너가 관리하는 자가 객체를 빈이라고 한다.

스프링 컨테이너

  • 스프링 빈의 생명 주기르 ㄹ관리하며, 생성된 스프링 빈들에게 추가적 기능을 제공한다.
  • IoC, DI
  • 제어의 흐름을 외부에서 관리한다.
  • 객체간 의존관계를 스프링 컨테이너가 런타임 과정에서 만들어 준다.

스프링 빈 등록하기

ComponentScan

  • 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아 넣어준다.
  • 이처럼 객체 의존관계를 외부에서 넣어주는것을 DI(Dependenct Injection),의존성 주입 이라고 한다.
  • @Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
  • @Controller, @Service, @Repository -> 해당 어노테이션을 들여다보면 @Component를 내장하고 있다.
  • 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(하나만 등록해 공유) 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다. 설정으로 싱글톤이 아니게 할 수는 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
  • 패키지의 하위를 뒤져서 등록하는거라 아무곳에나 생성하면 컴포넌트 스캔의 대상이 되지않는다. -> 이또한 설정으로 대상이 되게끔 할 수는 있다.

JAVA 코드로 등록

  • @Configuration과 @Bean 애노테이션을 이용해 스프링 빈을 등록한다. @Configuration을 이용하면 스프링 프로젝터에서 Configuration 역할을 하는 Class를 지정할 수 있다.
  • @Service, @Repository, @Autowired 어노테이션이 없는 상태에서 진행한다.
  • 스프링 실행파일과 동일 위치에 SpringConfig.JAVA 생성
 package hello.hellospring;
    import hello.hellospring.repository.MemberRepository;
    import hello.hellospring.repository.MemoryMemberRepository;
    import hello.hellospring.service.MemberService;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    public class SpringConfig {
         @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
        @Bean
        public MemberRepository memberRepository() {
          return new MemoryMemberRepository();
        }
}
  • @Configuration 어노테이션을 사용해 해당 파일이 빈을 등록할 파일이 될것임을 명시한다.
  • 빈을 등록하기 위해선 인스턴스를 생성하는 메서드 위에 @Bean 어노테이션을 사용한다.

권장 방식

  • XML에 등록하는 방법도 있지만, 현재는 거의 사용하지 않는다.
  • 스프링에서는 자동으로 빈 등록을 하는 방식을 권장한다.
  • @Bean은 외부 라이브러리를 Bean에 등록할 경우 사용한다.
  • 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.

참고

  • @Autowired 를 통한 DI는 helloConroller , memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
  • DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다.
    • 필드 주입은 좋지않다. 뭔가 바꿀수 있는 방법이 없다.
      • 즉, 외부 수정이 불가능하고 테스트 코드를 작성할 때 객체를 수정할 수 없다.
      • @Autowired로 의존성 남발할 수 있다.
      • final키워드를 통한 선언이 안되기 때문에 객체가 mutable하다.
    • setter injection의 방법은 누군가 컨트롤러를 호출하면 퍼블릭으로 열려 있어야 하기 때문에 퍼블릭 노출 단점
      • 즉, 객체의 변경 가능성이 열려있는 상태
      • 거의 없지만..주입받는 객체가 변경되어야만 할 때 사용
    • 생성자를 통해 주입하면 처음부터 조립 및 셋팅이 되는 시점에 생성자가 처음 들어오고 끝난다. -> 권장 방식
      • 생성자가 한 개만 있을경우에는 @Autowired 생략 가능하다.
      • 생성자로 한 번 의존관계를 주입하면, 생성자는 다시 호출될일이 없기 때문에 불변 객체 보장

 

'Frameworks > Spring' 카테고리의 다른 글

[Spring] BeanDefinition  (0) 2025.04.11
[Spring] 스프링 컨테이너 & 빈  (0) 2025.04.11
[Spring] Ioc,DI,Container  (0) 2025.04.11
[Spring] 객체 지향 프로그래밍  (0) 2025.04.11
[Spring] Intro  (0) 2025.04.10