티스토리 뷰

728x90
반응형

지난번 글에서 스프링 컨테이너에 빈을 등록하는 법에 대해 알아봤었다.

 

2022.08.12 - [개발/Spring] - [Spring]DI - 스프링 컨테이너(Container)와 빈(Bean)

 

[Spring]DI - 스프링 컨테이너(Container)와 빈(Bean)

지난번 글에서, IoC(Inversion of Control)는 DI(Dependency Injection)에 의해 구현된다고 했었다. 여기서 IoC는 제어 역전이라는 뜻을 가지며, 외부 프레임워크가 개발자의 코드를 호출해 실행된다. DI는 풀

gnidinger.tistory.com

이번 글에선 그 방법들에 대한 부연설명과 자바를 기반으로 한 컨테이너 설정에 대해 더 알아본다.

 

@ComponentScan

 

@ComponentScan은 @Component, @Service, @Repository, @Controller, @Configuration이 붙은

 

클래스와 빈을 찾아서 스프링 컨테이너에 빈을 등록시켜주는 애너테이션이다.

 

하지만 스프링 부트를 사용하면서 이 애너테이션을 직접 쓸 일은 많지 않은데,

 

이는 스프링 부트의 기본적인 설정을 선언해주는 @SpringBootApplication 애너테이션에

 

@ComponentScan이 포함되어 있기 때문이다.

 

때문에 별도로 애너테이션을 작성하지 않아도, 스프링 부트는 @ComponentScan 기능을 사용한다.

@Component

 

@Component는 클래스에 붙여 자동으로 스프링 컨테이너에 빈을 등록하는 방법이다.

 

위에 나온 @ComponentScan 기능이 스캔을 할 때 주어진 패키지 내에서 @Component가 적용된 클래스를 식별하고,

 

식별된 클래스들을 스프링 컨테이너를 통해 빈으로 등록시킨다.

 

(value = "value") 옵션으로 이름을 지정해줄 수 있으며, 지정하지 않으면 클래스 이름을 CamelCase로 변경해 사용한다.

 

@Component 외에도 @Controller , @Service, @Repository, @Configuration 등의 애너테이션을 추가할 수 있는데,

 

이는 이  가지 애너테이션이 모두 @Component 상속받고 있기 때문이다.

 

이는 인터페이스를 뜯어보면 더 명확하게 알 수 있다.

 

참고로 네 가지 애너테이션의 차이는 아래와 같다.

 

  • @Controller - 스프링 MVC로 인식
  • @Service - 특별한 처리는 하지 않으나, 핵심 비즈니스 계층임을 표시
  • @Repository - 스프링 데이터 접근 계층으로 인식, 발생하는 예외는 전부 DataAccessException으로 처리
  • @Configuration - 스프링 설정 정보로 인식, 빈이 싱글톤을 유지하도록 추가 처리

클래스 위에 해당 애너테이션을 적어주기만 하면 자동으로 빈 등록이 된다.

 

 

@Configuration, @Bean

 

이는 AppConfig.class 등의 빈 설정 클래스를 직접 만들어 빈을 등록하는 방법이다.

 

@Configuration은 클래스에 붙이며, 이 어노테이션이 붙은 클래스를 빈 설정을 담당하는 클래스로 선언한다.

 

@Bean 애너테이션은 빈 설정 클래스 안의 메서드에 붙이며, 해당 메서드가 리턴하는 객체를 빈으로 등록한다.

 

(name = "name") 옵션으로 이름을 지정해줄 수 있으며, 지정하지 않으면 메서드 이름을 CamelCase로 변경해 사용한다.

 

@Bean이 사용된 메서드는 매개변수를 의존성 선언을 위해 사용할 수도 있다.

 

추가로 @Configuration 없이도 @Bean을 사용할 수 있지만 이 경우 @Bean메서드가 빈 간의 의존성을 선언할 수 없다.

 

이를 lite모드라고 하는데, 지금은 @Bean을 사용하려면 반드시 클래스에 @Configuration을 붙여줘야 한다고 기억하자.

 

계속해서 방금 알아본 두 방식 간의 차이에 대해 정리하고 넘어가자.

 

  • @Component

    • 자동으로 스프링 컨테이너에 빈을 등록하는 방법
    • 클래스 레벨에서 선언
    • 스프링의 @ComponentScan 기능이 @Component 어노테이션이 달린 클래스를 자동으로 찾아서 빈으로 등록
    • 많은 경우 @Component를 이용한 자동 등록 방식을 사용하는 것이 좋음
    • @Component 하위 어노테이션으로 @Controller, @Service, @Repository, @Configuration 등이 있음

 

 

  • @Configuration, @Bean

    • 수동으로 스프링 컨테이너에 빈을 등록하는 방법
    • @Configuration은 클래스 레벨, @Bean은 메서드 레벨에서 선언
    • 개발자가 직접 제어가 불가능한 라이브러리를 빈으로 등록할 때 불가피하게 사용
    • 유지보수성을 높이기 위해 앱 전범위적으로 사용되는 클래스나 다형성을 활용하여 여러 구현체를 빈으로 등록할 때 사용
    • 1 이상의 @Bean 제공하는 클래스의 경우 반드시 @Configuration 명시해 주어야 싱글톤이 보장됨

애너테이션을 사용해 스프링 컨테이너를 구성하는 방법

 

@Import

 

클래스 단위의 종속성을 관리하는 애너테이션. @Configuration 애너테이션이 선언된 설정 클래스를 가져온다.

 

@Configuration으로 설정한 파일이 두 개 이상 있을 때 사용하며, 클래스 이름으로 호출하면 된다.

@Configuration
public class ConfigA {

    @Bean
    public A a() {
        return new A();
    }
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {

    @Bean
    public B b() {
        return new B();
    }
}

이런 경우 컨테이너를 인스턴스화 할 때, ConfigA.class와 ConfigB.class 모두 지정하는 대신 ConfigB.class만 넣으면 된다.

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);

    // now both beans A and B will be available
    A a = ctx.getBean(A.class);
    B b = ctx.getBean(B.class);
}

ctx에 @Import(ConfigA.class)를 받은 ConfigB.class 사용으로 인해 ctx.getBean(A.class)가 가능해지는 것이다.

 

물론 두 개 이상의 클래스를 @Import 하는 것도 가능하다. @Import({A.class, B.class})와 같은 식으로 사용하면 된다.

 

실제 상황에서 빈은 여러 개의 @Configuration클래스에 걸쳐 의존하는 경우가 많다.

 

@Autowired

 

 애너테이션은 필드, 메서드, 생성자, setter에 붙일 수 있으며, 빈을 가져오는 가장 기본적인 방법이다.

 

필드, setter에 붙여서 사용할 경우 반드시 기본 생성자가 정의되어 있어야 하며

 

특별히 필드에 붙이는 경우엔 setter를 통해 주입되고, setter가 없을 경우 컴파일 과정에서 자동으로 추가된다.

 

스프링에서 의존성 주입을 할 때 주로 쓰이며, 타입에 따라 알아서 빈을 주입해 준다.

@Service
public class BookService {
    private BookRepository bookRepository;

    @Autowired
    public BookService(BookRepository bookRepository){
        this.bookRepository = bookRepository;
    }    
}

이때 설정 파일에는 주입될 빈이 정의되어 있어야 하며, 빈이 하나의 생성자만 정의하는 경우엔 @Autowired를 생략 가능하다.

 

설정 파일에서 빈의 의존성을 설정해주지 않고도 간편하게 의존성이 주입된 것을 확인할 수 있다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함