영호

[Spring] 컴포넌트 스캔 본문

Spring

[Spring] 컴포넌트 스캔

0h0 2022. 12. 26. 23:19

우선 Spring의 특징

Spring은 객체지향의 장점을 살릴 수 있도록 도와줍니다. 객체지향 프레임워크는 객체들의 집합으로 객체들 간의 협력을 통해 기능을 완성시키기 때문에, 객체 간 의존관계를 잘 관리해야 합니다.

 

그렇다면, Spring에서는 어떤 식으로 객체들을 관리하는지 알아보겠습니다. 우선, Spring에서는 이러한 객체들을 빈(bean)이라는 개념으로 표현합니다. 스프링 컨테이너에 빈들을 등록하고 관리하는 방식입니다. 

 

빈을 등록하는 방법에는 @Bean, 컴포넌트 스캔을 활용하는 방법 2가지가 있습니다. 이 2가지 방법을 비교해 보겠습니다.

 

@Bean

@Configuration
public class ApplicationConfig {

    @Bean
    public ARepo aRepo() {
        return new ARepo();
    }

    @Bean
    public AService aService() {
        return new AService(new ARepo());
    }
}

 

객체 관리를 담당하는 클래스를 생성한 뒤 @Configuration어노테이션을 작성합니다.

이후 스프링 컨터이너에서 관리하고 싶은 빈들의 생성, 의존관계 주입을 수행하는 메서드를 작성하면서 위에 @Bean어노테이션을 작성해 줍니다.

 

aRepo() 메서드의 경우 스프링 컨테이너에 "aRepo : 객체" 형태로 key에는 return type의 앞 글자만 소문자로 바꾼 String이 설정되고, value는 해당 객체가 할당되어 스프링 컨테이너에 등록됩니다.

 

aService()처럼 의존관계를 설정할 수도 있습니다.

컴포넌트 스캔

위 방법처럼 수동으로 모든 객체를 생성하고 의존관계를 주입한다면 양도 많아지고, 이 과정에서 분명 실수도 나올 것입니다. 그래서 이러한 작업들을 Spring에서는 컴포넌트 스캔을 통해 개발자가 어노테이션만 적절하게 작성하면 빈 생성, 의존관계 주입을 자동으로 해줍니다.

@Configuration
@ComponentScan
public class ApplicationConfig {
}

@Configuration, @ComponentScan을 같이 사용하게 되면 해당 클래스를 통해 모든 빈 생성, 의존관계 주입이 완료됩니다.

컴포넌트 스캔 동작 방식

Spring은 @ComponentScan이 작성된 클래스가 존재하는 패키지 하위에 존재하는 모든 클래스 파일 중 @Component어노테이션이 붙은 객체들을 모두 스프링 컨테이너에 빈으로 등록합니다.

이렇게 빈 등록이 끝나면 Spring은 @Autowired를 통해 의존관계 주입을 시작합니다.

 

@Controller, @Service, @Repository, @Configuration을 타고 들어가면 @Component가 붙어있는 것을 볼 수 있습니다. 그래서 해당 어노테이션도 컴포넌트 스캔의 대상이 됩니다.

주의점

이 과정에서  아래 코드처럼 스프링 컨테이너에 등록되는 key값을 설정할 수 있습니다. 만약 key값이 중복되는 빈들이 있다면 예외가 발생하니 조심해야 합니다.

public class A {
}
@Component
public class B {
}
@Configuration
@ComponentScan
public class TestConfig {
    @Bean(name = "b")
    public A a() {
        return new A();
    }
}

현재 A를 @Bean(name = "b")를 통해 b를 key값으로 스프링 컨테이너에 등록했고, @Component를 통해 B를 등록하는 과정에서 b로 변환되어 스프링 컨테이너에 빈이 등록됩니다. 

이 상황에서 Spring을 동작하면 에러가 발생하고 아래와 같은 설명이 나옵니다.

The bean 'b', defined in class path resource [클래스 파일 존재 경로], could not be registered. A bean with that name has already been defined in file [클래스 파일 존재 경로] and overriding is disabled.

그렇기 때문에 b라는 key값이 중복이 되어 에러가 발생한 것입니다.

Comments