spring.factories

2024. 10. 16. 17:04Spring Boot/Spring Boot Auto Configuration

스프링의 SpringFactoriesLoader 클래스는 META-INF/spring.factories 파일에서 특정 타입의 팩토리 구현체들을 로드하고 인스턴스화합니다. 이 과정은 스프링의 자동 구성(Auto Configuration) 메커니즘에서 중요한 역할을 하며, 스프링 부트에서 많이 사용됩니다.

스프링에서의 spring.factories 파일 역할

  • spring.factories 파일은 스프링 부트와 스프링 프레임워크에서 사용하는 메타데이터 파일로, 클래스패스에 있는 자동 구성 클래스나 팩토리 클래스들을 정의하는 파일입니다.
  • 이 파일은 META-INF/spring.factories 경로에 위치하며, 여러 JAR 파일에 포함될 수 있습니다.
  • 스프링 부트는 이 파일을 통해 자동 구성 클래스, 애플리케이션 초기화, 리스너, 후처리기 등 다양한 스프링 컴포넌트를 로드하고 인스턴스화합니다.

SpringFactoriesLoader의 역할

SpringFactoriesLoader는 META-INF/spring.factories 파일을 읽어 특정 타입의 팩토리 구현체(factory implementation)들을 클래스 로더를 통해 로드하고, 인스턴스화하는 역할을 합니다. 이 작업은 스프링 부트의 자동 구성 시스템이나 초기화 작업에서 매우 중요한 부분입니다.

동작 과정 설명

  1. spring.factories 파일에서 팩토리 클래스 로드:
    • SpringFactoriesLoader는 클래스패스에 있는 모든 META-INF/spring.factories 파일을 읽습니다.
    • 이 파일은 키-값 쌍으로 구성되어 있으며, 팩토리 인터페이스나 추상 클래스가 키로, 그 구현체 클래스들이 값으로 나열됩니다.예시 META-INF/spring.factories 파일:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
  1. 팩토리 구현체 로드:
    • SpringFactoriesLoader는 특정 타입(예: EnableAutoConfiguration)의 모든 구현체들을 찾고 클래스 로더를 사용해 해당 구현체들을 로드합니다.
    • 이 과정에서 주어진 타입의 팩토리 구현체들이 동적으로 로드됩니다.
  2. 팩토리 구현체 인스턴스화:
    • 로드된 클래스들은 리플렉션을 통해 인스턴스화됩니다.
    • 스프링은 주어진 인자나 기본 생성자를 사용해 구현체의 인스턴스를 생성할 수 있습니다.
  3. 팩토리 구현체 반환:
    • 인스턴스화된 팩토리 구현체들은 스프링의 컨텍스트 초기화 과정이나 애플리케이션 실행 과정에서 사용되며, 주어진 역할을 수행하게 됩니다.

구체적인 메서드 동작: loadFactories()

스프링은 SpringFactoriesLoader의 loadFactories 메서드를 사용해 META-INF/spring.factories 파일에 정의된 특정 타입의 팩토리들을 로드하고 인스턴스화합니다.

public static <T> List<T> loadFactories(Class<T> factoryType, ClassLoader classLoader) {
    List<String> factoryNames = loadFactoryNames(factoryType, classLoader);
    List<T> result = new ArrayList<>(factoryNames.size());
    for (String factoryName : factoryNames) {
        result.add(instantiateFactory(factoryName, factoryType, classLoader));
    }
    return result;
}
  1. loadFactoryNames(): spring.factories 파일에서 주어진 타입의 팩토리 이름들을 불러옵니다.
  2. instantiateFactory(): 불러온 팩토리 이름을 기반으로, 리플렉션을 통해 해당 클래스를 인스턴스화합니다.

어떤 경우에 사용되나?

  • 자동 구성 클래스 로드:
    • 스프링 부트의 자동 구성(Auto Configuration) 과정에서, spring.factories 파일을 통해 자동 구성 클래스들을 로드하고, 해당 클래스를 자동으로 인스턴스화하여 애플리케이션 설정을 구성합니다.
  • 초기화 클래스 로드:
    • 스프링 부트에서 애플리케이션 초기화 시점에, ApplicationContextInitializer나 ApplicationListener 같은 초기화 클래스나 리스너들을 spring.factories 파일을 통해 로드하여, 애플리케이션 실행 전에 초기화 작업을 수행합니다.

예시: 자동 구성 클래스 로딩

java

List<EnableAutoConfiguration> autoConfigurations = SpringFactoriesLoader.loadFactories(EnableAutoConfiguration.class, getClass().getClassLoader());

코드 복사

위의 코드는 EnableAutoConfiguration 인터페이스를 구현한 모든 자동 구성 클래스를 spring.factories 파일에서 로드하고, 이를 인스턴스화합니다.

요약

  • SpringFactoriesLoader는 META-INF/spring.factories 파일을 통해 특정 타입의 팩토리 구현체들을 클래스 로더를 사용해 로드하고, 리플렉션을 통해 인스턴스화하는 역할을 합니다.
  • 이 과정은 스프링 부트의 자동 구성 시스템이나 초기화 작업에서 매우 중요하게 사용되며, 팩토리 클래스들을 동적으로 로드하고 인스턴스화하여 필요한 설정 작업을 수행합니다.

spring.factories가 없는 경우

spring.factories 파일이 없는 이유는 해당 .jar 파일이 Spring의 자동 설정이나 확장 기능을 필요로 하지 않는 경우이기 때문입니다. 이 파일은 Spring 애플리케이션에서 자동으로 빈을 구성하거나 특정 기능을 활성화하기 위해 사용되지만, 모든 라이브러리가 이러한 자동 설정 메커니즘을 필요로 하지는 않습니다.

다음은 spring.factories 파일이 없는 이유와 그럴 수 있는 경우에 대한 상세 설명입니다.

1. Spring 자동 설정을 사용하지 않음

spring.factories 파일은 주로 Spring Boot와 같이 자동 설정(Auto Configuration) 기능을 지원하는 경우에 사용됩니다. 자동 설정은 애플리케이션 환경에 따라 필요한 빈을 자동으로 등록하고 설정을 적용하는 방식입니다. 그러나 모든 라이브러리가 자동 설정을 필요로 하는 것은 아닙니다. Spring의 자동 설정은 주로 개발 편의성을 높이기 위해 사용되는 선택적 메커니즘이기 때문에, 다음과 같은 이유로 spring.factories 파일이 포함되지 않을 수 있습니다.

  • 자동 설정이 필요 없는 라이브러리: 많은 라이브러리는 Spring과 상관없이 독립적으로 사용할 수 있습니다. 예를 들어, 단순한 유틸리티 라이브러리는 Spring 컨텍스트에 빈을 자동으로 등록할 필요가 없습니다. 이런 경우에는 수동으로 빈을 구성하거나, 별도의 설정 없이 라이브러리 기능을 사용할 수 있기 때문에 spring.factories 파일이 필요하지 않습니다.
  • 전통적인 Spring 설정 방식 사용: Spring은 오래전부터 XML 설정이나 Java 기반 설정(@Configuration)을 사용하여 빈을 등록했습니다. 이러한 전통적인 설정 방식은 수동으로 구성되기 때문에, Spring Boot의 자동 설정 메커니즘을 필요로 하지 않습니다. 이 경우 spring.factories 파일 없이도 애플리케이션이 정상적으로 동작합니다.

예시:

@Configuration
public class MyManualConfig {
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

위와 같이, 수동 설정으로 빈을 등록하는 경우, 자동 설정을 위한 spring.factories가 필요하지 않습니다.

2. 독립적인 라이브러리 또는 비-Spring 라이브러리

많은 라이브러리는 Spring에 종속되지 않고 독립적으로 동작하는 설계 철학을 따릅니다. 이러한 라이브러리들은 Spring Framework와 직접적으로 연관되지 않으며, 단지 특정 기능(예: JSON 처리, 데이터베이스 연결, 파일 처리 등)을 제공하는 도구일 뿐입니다.

이 경우, Spring의 자동 설정이나 확장 기능을 염두에 두고 설계되지 않기 때문에 spring.factories 파일이 필요하지 않습니다.

예시:

  • Jackson: Spring에서 자주 사용하는 JSON 처리 라이브러리인 Jackson은 자체적으로 Spring에 종속되지 않고, 독립적으로 동작합니다. Spring Boot는 자동 설정을 통해 Jackson 관련 빈을 자동으로 등록할 수 있지만, Jackson 자체는 spring.factories를 포함하지 않습니다. 이는 Jackson이 자체적으로 Spring과 연관된 설정을 필요로 하지 않기 때문입니다.
  • Apache Commons: commons-lang, commons-io와 같은 Apache Commons 라이브러리는 일반적인 유틸리티 기능을 제공하며, Spring과 무관하게 사용됩니다. 이러한 라이브러리는 spring.factories 파일이 필요하지 않습니다.

3. 특정 프레임워크나 모듈 내에서 자동 설정을 원하지 않는 경우

어떤 경우에는 Spring의 자동 설정이 원치 않거나, 애플리케이션에서 더 많은 제어가 필요한 상황일 수 있습니다. 이때는 spring.factories 파일 없이 수동 설정을 통해 필요한 빈을 직접 정의합니다.

  • 커스텀 설정 요구사항: 만약 특정 애플리케이션이 고도로 커스터마이즈된 설정을 요구한다면, 자동 설정은 필요하지 않거나, 오히려 설정을 복잡하게 만들 수 있습니다. 이런 경우에는 수동으로 빈을 정의하고, 직접 관리하는 것이 더 적합합니다.
  • Spring Boot가 아닌 애플리케이션: Spring Boot는 자동 설정과 관련된 메커니즘을 제공하지만, Spring Boot를 사용하지 않는 일반 Spring Framework 애플리케이션에서는 spring.factories가 필수적이지 않습니다. XML이나 Java Config를 통해 설정을 직접 관리하기 때문에, 자동 설정 파일을 포함할 필요가 없습니다.

4. 단순한 라이브러리 의존성

단순한 라이브러리들은 Spring 컨텍스트에 자동으로 어떤 빈이나 설정을 등록할 필요가 없기 때문에 spring.factories를 포함하지 않을 수 있습니다. 이러한 라이브러리는 단지 다른 라이브러리에 의존성을 제공하거나, 특정 기능을 제공하는 도구로 동작합니다.

예시:

  • SLF4J: 로깅 인터페이스를 제공하는 SLF4J는 Spring과 상관없이 로깅 기능을 제공합니다. 이 경우에도 자동 설정이 필요 없으며, 단순히 인터페이스로서 기능을 제공합니다.
  • Hibernate Core: Hibernate는 ORM 프레임워크로 Spring과 통합될 수 있지만, Spring에 의존적이지 않으며 자체 설정 파일을 통해 동작합니다. Spring Boot와 함께 사용할 때 Hibernate 관련 자동 설정을 적용하려면 Spring Boot가 자동 설정을 제공하지만, Hibernate 자체는 Spring 설정을 관리하지 않기 때문에 spring.factories가 필요하지 않습니다.

5. 외부 또는 타사 라이브러리

타사 라이브러리 중 일부는 Spring 생태계와 완전히 분리되어 작동하며, spring.factories 파일이 필요하지 않은 경우도 많습니다. 이러한 라이브러리들은 Spring 프레임워크와의 직접적인 통합 없이, 필요한 기능을 자체적으로 제공합니다.

6. 테스트 또는 경량 라이브러리

테스트 라이브러리나 특정 상황에서만 사용되는 경량 라이브러리 또한 spring.factories를 필요로 하지 않을 수 있습니다. 이러한 라이브러리는 테스트 목적으로만 사용되거나, 애플리케이션에서 특정 역할을 수행할 때만 사용되기 때문에, Spring 자동 설정과 관련이 없을 수 있습니다.

결론

spring.factories가 없는 .jar 파일은 자동 설정이나 확장 포인트를 제공하지 않는 라이브러리이거나, Spring과 직접적인 연관이 없는 경우입니다. 이러한 라이브러리는 주로 다음과 같은 경우에 해당됩니다:

  • 독립적인 유틸리티 라이브러리 또는 비-Spring 라이브러리
  • 수동으로 빈을 등록하거나 전통적인 설정 방식을 사용하는 경우
  • 특정 애플리케이션에서 제어를 위해 자동 설정을 사용하지 않는 경우
  • 단순 의존성 제공 라이브러리

이러한 경우에는 spring.factories 파일이 필요하지 않으며, Spring 애플리케이션에서 해당 라이브러리를 사용할 때는 주로 수동 설정이나 직접적인 빈 등록이 필요할 수 있습니다.

'Spring Boot > Spring Boot Auto Configuration' 카테고리의 다른 글

DeferredImportSelector  (0) 2024.10.17
spring-boot-autoconfigure.jar  (0) 2024.10.16
Project Classpath  (0) 2024.10.16
@AutoConfigurationPackage  (0) 2024.10.16
@EnableAutoConfiguration  (0) 2024.10.16