스프링 부트 - 자동구성 3

    정리

    • 외부 라이브러리를 직접 만들고 그것을 프로젝트에 라이브러리로 불러서 적용해봄.
      • 그런데 라이브러리를 사용하는 클라이언트 개발자 입장을 생각해보면, 라이브러리 내부에 어떤 빈을 등록해야하는지 알아야 하고, 그것을 하나씩 다 빈으로 등록해야 함. 만약 초기 설정이 복잡하다면, 사용자 입장에서는 상당히 귀찮은 작업이 될 수 있음. 
      • 이런 부분을 자동으로 처리해주는 것이 스프링 부트의 Auto Configuration임.

     


    순수 라이브러리 만들기

    • @AutoConfiguration을 이해하기 위해서는 라이브러리가 어떻게 사용되는지 이해가 필요하다.
    • 앞서 생성한 Memory 패키지를 여러 곳에서 사용할 수 있도록 라이브러리로 만들어보자. 
    • 여기서는 순수 라이브러리를 만들어서, 특정 프로젝트에서 수동으로 스프링 빈으로 등록해서 사용하는 작업을 진행한다. 

    기본 패키지 생성

    • 프로젝트 설정 순서
      • memory-v1-start의 폴더 이름을 memory-v1으로 변경
      • 프로젝트 임포트
    // build.gradle
    plugins {
        id 'java'
    }
    
    group = 'memory'
    sourceCompatibility = '17'
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web:3.0.2'
        compileOnly 'org.projectlombok:lombok:1.18.24'
        annotationProcessor 'org.projectlombok:lombok:1.18.24'
        testImplementation 'org.springframework.boot:spring-boot-starter-test:3.0.2'
    }
    
    test {
        useJUnitPlatform()
    }
    • 스프링 부트 플러그인을 사용하게 되면 앞서 설명한 실행 가능한 Jar 구조를 기본으로 만듬.
    • 여기서는 실행 가능한 Jar가 아니라, 다른 곳에 포함되어서 사용할 순수 라이브러리 Jar를 만드는 것이 목적이므로 스프링 부트 플러그인을 사용하지 않음. → jar의 MANIFEST 파일을 보면 빈 파일이 되는 것을 알 수 있음. 
    • 스프링 컨트롤러가 필요하므로 Spring-boot-stater-web 라이브러릴 선택함. 
    • 스프링 부트 플러그인을 사용하지 않아서 버전을 직접 명시했다. 

     


    패키지 내에 내용 추가

    패키지 내에는 앞서 생성한 아래 클래스들을 추가한다.

     


    Jar 파일 생성해보기 

     

    $ ./gradlew clean build
    $ cd build/libs
    • 위 명령어를 이용해서 Jar 파일을 만든다. 

    • Jar 파일을 만들면 build/libs에 저장되는 것을 확인할 수 있다.

    • Jar 파일의 압축을 풀면 클래스 파일과 MANIFEST.MF 파일이 있다.
    • 다른 곳에서 라이브러리 형태로 사용될 것이기 때문에 MANIFEST.MF 파일에는 아무것도 기록되어 있지 않다. 

     


    순수 라이브러리 사용하기 

    방금 생성한 memory-v1 라이브러리를 사용하는 프로젝트 project-v1을 생성해본다. 

    • 프로젝트 설정 순서
      • project-v1-start를 project-v1으로 변경하자.

      앞서 만든 memory-v1.jar 라이브러리를 project-v1에 적용해보자. 

     

    라이브러리 추가

    • project-v1/libs 폴더를 생성하자. (반드시 libs로 생성해야함. )
    • jar 파일을 project-v1/libs에 저장한다. 그리고 build.gradle에 해당 jar 파일을 사용하도록 수정해야 함. 
      • implementation files(...)
    // build.gradle 
    ...
    
    dependencies {
        implementation files('libs/memory-v1.jar') // 추가
        implementation 'org.springframework.boot:spring-boot-starter-web'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    • 위와 같이 build.gradle 파일을 수정해서 라이브러리로 만든 jar 파일을 사용하도록 만들어야 함. 

    • build.gradle에서 포함되도록 했으면, libs의 .jar 파일이 위와 같이 인식된다. 
    • 압축을 푼 것은 아니지만 IDE 자체에서 Depth를 확인할 수 있게 됨. 
    // 스프링 빈으로 등록
    @Configuration
    public class MemoryConfig {
    
        @Bean
        public MemoryFinder memoryFinder() {
            return new MemoryFinder();
        }
    
        @Bean
        public MemoryController memoryController() {
            return new MemoryController(memoryFinder());
        }
    }
    • 스프링부트의 Auto Configuration을 사용하는 것이 아니기 때문에 빈을 직접 등록해줘야 함. 
    • Memory 라이브러리(외부 라이브러리, memory-v1)의 MemoryController, MemoryFinder를 스프링 빈으로 등록한 후에 정상적으로 동작하는지 살펴보자.
    http://localhost:8080/memory

    이 주소로 접속해서 값이 들어오는지 살펴보면 됨 

     


    자동 구성 라이브러리 만들기 (memory-v2)

    • 라이브러리를 사용하는 개발자들이 손쉽게 사용할 수 있도록 스프링부트의 AutoConfiguration을 이용해서 모든 구성이 자동으로 처리되도록 해보자.
    • 기존 memory-v1을 개선한 memory-v2를 생성해야함. 

     

    프로젝트 설정

    • memory-v1 프로젝트를 memory-v2로 복사 붙여넣기함
    • settings.gradle의 rootProject.name을 memory-v2로 바꿔줘야함. 
      • 이름이 바뀌었으니, RootPorject의 이름을 당연히 바꿔줘야 함. 

     

     

    memory-v2 자동 설정하도록 바꾸기 

    @AutoConfiguration
    @ConditionalOnProperty(name = "memory", havingValue = "on")
    public class MemoryAutoConfig {
        
        @Bean
        public MemoryFinder memoryFinder() {
            return new MemoryFinder();
        }
    
        @Bean
        public MemoryController memoryController() {
            return new MemoryController(memoryFinder());
        }
    }
    • @AutoConfiguration
      • 스프링 부트가 제공하는 자동 구성 기능을 적용할 때 사용하는 어노테이션이다.
      • 스프링 프레임워크는 시작할 때, ImportSelector를 이용해 @AutoConfiguration 어노테이션이 붙은 모든 클래스를 설정 정보로 등록한 후에, 자동 등록을 함. 
    • @ConditionalOnProperty
      • memory = on이라는 환경 정보가 있을 때, 라이브러리를 적용한다. (스프링 빈을 등록한다.) 
      • 라이브러리를 가지고 있더라도 상황에 따라서 해당 기능을 켜고 끌 수 있게 유연한 기능을 제공한다. 

     


    자동 구성 대상 지정 - 매우 중요

    • 스프링 부트 자동 구성을 적용하려면, 아래 파일에 자동 구성 대상을 꼭 지정해줘야 함. 
    • 파일 생성
      • src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
    • 파일 내용은 아래를 참고하자.
    // org.springframework.boot.autoconfigure.AutoConfiguration.imports
    memory.MemoryAutoConfig
    • 앞서 만든 자동 구성인 memory.MemoryAutoConfig를 패키지를 포함해서 지정해줘야함.
    • 스프링 부트는 시작 시점에 org.springframework.boot.autoconfigure.AutoConfiguration.imports의 정보를 읽어서 자동 구성으로 사용함. 따라서 내부에 있는 MemoryAutoConfig가 자동으로 실행됨. 
      • 엄밀히 말하면 Spring.format이 org.springframework.boot.autoconfigure.%s.imports로 되어있으며, %s에 @AutoConfiguration의 이름이 들어가는 것임.

     


    자동 구성 라이브러리 사용하기

    • project-v2-start → project v2로 바꾼 후, libs/ 폴더에 memory-v2.jar를 복사한다.
    • build.gradle에서 implementation files()를 이용해서 memory-v2.jar를 import해서 memory-v2 라이브러리를 사용할 수 있도록 한다. 
    • 라이브러리를 넣은 후 VM Option에 -Dmemory=on 넣고 빼면서 localhost:8080/memory에 접속해 정상적으로 동작하는지 확인해보면 됨.

     

    댓글

    Designed by JB FACTORY