> For the complete documentation index, see [llms.txt](https://wannaqueen.gitbook.io/spring5/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wannaqueen.gitbook.io/spring5/spring-5.0/1/1.10-by-ys.md).

# 1.10 클래스패스 스캔 및 관리 by ys

{% hint style="info" %}
**BeanDefinition과 BeanFactoryPostProcessor  (혹은 BeanDefinitionRegistryPostProcessor)**

**"애초에 스프링 빈은 어떻게 생성되고 주입될까?" (아래 그림 참고)**

**아래 그림**은 크게 두 가지 단계(Phase)로 구분되어 있습니다. 한 번만 일어나는(Happens only once) 처리 단계와 각각의 빈들에 대해 일어나는(Happens for each bean) 단계입니다. 그림의 왼쪽 부분과 오른쪽 부분이죠.&#x20;

다소 복잡해 보이지만 그림의 내용을 매우 간단히 설명하면, **beans.xml과 같은 스프링 컨텍스트 파일을 로딩**한 뒤, 몇몇 절차를 거쳐 **"빈에 대한 최종 정의(Final Bean Definition)"**&#xB97C; 생성하면, 그것을 이용하여 **실제 스프링 빈을 생성하면서 의존성 주입(Dependency Injection)를 한다**는 것입니다. 즉, 스프링 프레임워크를 잘 모르는 개발자들의 막연한 생각과는 달리, **빈에 대한 정의를 먼저 수립하고 그 뒤에 실제 빈 인스턴스를 생성하는 절차**를 따르게 됩니다.

여기서 주목해야 할 점은, 빈에 대한 최종 정의를 만들 때, 설정 파일로부터 로딩된 빈 정의 목록에 **BeanFactoryPostProcessor라는 인터페이스가 개입할 수 있다**는 것입니다. 설정파일을 통해, 혹은 등록된 stereotype을 통해 이미 알고있는 빈에 대한 정의에 추가로 "개발자의 필요에 따라" 특정 빈들을 스프링이 로딩하도록 설정할 수 있다는 것인데, 다시 말해 "**어떤 인터페이스가 @Mapper 어노테이션으로 지정되어 있다면 스프링 빈으로 등록하라"** 라고 명령할 수 있다는 말입니다.

BeanFactoryPostProcessor 인터페이스는 [Functional Interface](http://wiki.sys4u.co.kr/pages/viewpage.action?pageId=7766426)로, postProcessBeanFactory(ConfiguratbleListableBeanFactory) 메소드 하나를 선언하고 있습니다. **이 인터페이스에 대한 구현체(클래스)를 이용하여 프로그램적으로 새로운 빈을 등록할 수 있습니다.** 이에 대한 상세한 내용은 [스프링 documentation](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html)을 참고하시길 바랍니다.

&#x20;BeanFactoryPostProcessor를 상세히 다뤄지지 않는 이유는 BeanFactoryPostProcessor보다 더 유용한 대체자로 **BeanDefinitionRegistryPostProcessor**가 있기 때문입니다. 이 새로운 인터페이스를 이용하면 - 말 그대로 **BeanDefinitionRegistry**를 이용하여 - 좀더 쉽게 빈에 대한 정의를 등록할 수 있습니다.&#x20;

위 그림에는 표현되어 있지 않지만, **빈 정의(Bean Definition)들은 인덱싱(indexing) 과정을 통해 BeanDefinitionRegistry에 등록**됩니다. 그리고 BeanDefinitionRegistry에 등록되어 있는 빈 정의들은 (singleton 타입인 경우) 이후 단계에서 실제 빈 인스턴스로 ApplicationContext에 등록됩니다.&#x20;
{% endhint %}

![](https://3140643518-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWdhssr0w9IqAHmA-ke%2F-LYeUQ3ZX8qq9zb2Agsl%2F-LYeUTCISoSBsu3GZgXH%2Fimage.png?alt=media\&token=a9f9c4ae-3d65-4d27-ba71-5987a9d0e452)

이 장의 대부분의 예제는 **XML을 사용하여**( Spring 컨테이너 내에서 각각 `BeanDefinition`을 생성하는 )**구성 메타 데이터를 지정합니다**. 이전 섹션 ( [annotation 기반 컨테이너 구성](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-annotation-config))는 소스 레벨 annotation을 통해 많은 구성 메타 데이터를 제공하는 방법을 보여줍니다. 그러나 이러한 예제에서도 "기본"bean 정의는 XML 파일에 명시 적으로 정의되지만 annotation은 종속성 삽입 만 실행합니다. 이 절에서는 classpath를 스캔하여 후보 구성 요소를 내재적으로 감지하는 옵션에 대해 설명합니다. 후보 컴포넌트는 필터 기준과 일치하고 해당 bean 정의가 컨테이너에 등록 된 클래스입니다. 따라서 Bean 등록을 수행하기 위해 XML을 사용할 필요가 없습니다. 대신 어노테이션 (예: `@Component`), AspectJ 유형 표현식 또는 사용자 정의 필터 기준을 사용하여 컨테이너에 등록 된 Bean 정의가있는 클래스를 선택할 수 있습니다.

|   | Spring 3.0부터는 Spring JavaConfig 프로젝트가 제공하는 많은 기능들이 핵심 Spring 프레임 워크의 일부이다. 이를 통해 전통적인 XML 파일을 사용하는 대신 Java를 사용하여 Bean을 정의 할 수 있습니다. `@Configuration`, `@Bean`, `@Import`, 그리고 `@DependsOn`이러한 새로운 기능을 사용하는 방법의 예에 대한 annotation을 살펴보세요 |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
