@SpringBootTest에서 다른 프로필을 동적으로 사용하는 방법

7381 단어
실현 절차
  • 테스트 클래스 표시 @Active Profiles(resolver = Profiles Resolver.class)
  • 사용자 정의 클래스 프로필스 Resolver는 인터페이스Active 프로필스 Resolver를 실현하고 인터페이스에서 유일한 방법resolve(Class> targetClass)
  • 을 실현한다.
  • maven-surefire-plugin 플러그인에 설정
  •  
        ${spring.profiles.active}
    
    

    구현은 다음과 같습니다.
    1. 치수 설정
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {PetstoreApp.class}, //     application    PetstoreApp
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @ActiveProfiles(resolver = ProfilesResolver.class)
    public abstract class BaseResourceTest {
    }
    

    이 클래스가 존재하는 의미는 다른 클래스의 ResourceTest가 그것을 계승하고 모든 통합 테스트를 한 번에 실행하기 위해서입니다.각 ResourceTest에서 Application을 초기화하여 실행 속도가 느려지지 않도록 합니다.
    주의 abstract 키워드가 abstract 키워드를 사용하지 않으면 maven-surefire-plugin에서 다음과 같은 오류가 발생합니다.
    Tests in error: BaseResourceTest.initializationError » No runnable methods
    2. 다음과 같은 사용자 정의 클래스 ProfilesResolver를 구현합니다.
    import org.springframework.test.context.ActiveProfilesResolver;
    
    public class ProfilesResolver implements ActiveProfilesResolver {
        @Override
        public String[] resolve(Class> aClass) {
            String activeProfiles = System.getProperty("spring.profiles.active");
            return new String[] {activeProfiles != null ? activeProfiles : "local"};
        }
    }
    

    이것은 우리가 시스템 변수에서spring을 읽을 것을 표시합니다.profiles.active, 그런데 이 변수는 어디에서 오나요?내가 먼저 생각한 것은 마벤트의 프로필에properties를 설정하는 것이다. 다음과 같다.
    
            local
            
                local
            
    
    

    이렇게 하면 명령줄에서 mvn test -Plocal 를 실행할 때 local 프로필을 사용했습니다.이에 따라 마벤트의 상하문에서spring.profiles.active 변수의 값은local입니다.
    그러나 테스트를 실행할 때, 우리 Profiles Resolver의 System.getProperty("spring.profiles.active") 는 시종일관 null 되돌아왔다.사실 이치는 매우 간단하다. 마븐에서 정의한properties는 모두 마븐 자체 (각종 플러그인 포함) 에 사용되며, 응용 프로그램에 전달되지 않는다.
    참고:
    properties에 정의된spring.profiles.active는 사실 주로 플러그인 마븐-resources-plugin에 사용되며, 구체적으로는 비고를 참고하십시오.
    3. 정의systemPropertyVariables그래서 우리는 정의systemPropertyVariables가 필요하다. 말 그대로 시스템 변수의 정의로 응용 프로그램에서 사용할 수 있다System.getProperty("spring.profiles.active").
    어디에 두면 좋을까요?테스트 플러그인 중 가장 적합합니다!
    따라서 다음과 같은 구성이 있습니다.
    
    org.apache.maven.plugins
    maven-surefire-plugin
    
        alphabetical
        
            ${spring.profiles.active}
        
    
    
    
    

    위properties의 설정과 결합하여 우리가 다시 mvn test -Plocal실행할 때spring이라는 이름을 얻을 수 있습니다.profiles.active의 시스템 변수입니다. 값은 ${spring.profiles.active}에 의해 결정됩니다.여기가 바로 local입니다.
    비고
    properties에서spring.profiles.active의 다른 용도는 마븐의properties에서spring을 정의하면 됩니다.profiles.active, 실행 mvn spring-boot:run -Plocal 할 때spring boot applicaiton-local.yml 프로필을 사용합니다.
    왜 이러지?상식적으로 볼 때spring-boot-maven-plugin의 설정 항목은 우리가 설정한propertiesspring.profiles.active를 자동으로 읽지만 이 플러그인의 문서를 한 번 보면 플러그인의configuration에서profiles 파라미터를 설정하거나 수동으로run에 전송하지 않는 한 발견할 수 있습니다.profiles 시스템 변수 example, 그렇지 않으면 플러그인 자체 (나처럼 플러그인의 원본 코드를 한 번 훑어볼 수 있음),spring을 사용하는 어떤 프로필을 사용할 수 있는지 감지할 수 없습니다!그래서 이 가설은 성립되지 않는다.
    정답은bootstrap.yml 중에!**다음은 Resources/config/bootstrap.yml의 내용
    spring:
        application:
            name: petstore
        profiles:
            # The commented value for `active` can be replaced with valid Spring profiles to load.
            # *       *
            # Otherwise, it will be filled in by maven when building the WAR file
            # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
            active: #spring.profiles.active#
    

    이곳의 주석은 매우 유용하다. WAR 패키지를 구축할 때, 마븐은 #spring.profiles.active#을 진정한 값으로 바꾸는 것을 도와줄 것이다.
    이건 또 어떻게 하는 거지?모든 것은 maven-resources-plugin의 공로입니다.
    
        org.apache.maven.plugins
        maven-resources-plugin
        ${maven-resources-plugin.version}
        
            
                default-resources
                validate
                
                    copy-resources
                
                
                    target/classes
                    false
                    
                        # 
                    
                    
                        
                            src/main/resources/
                            true
                            
                                **/*.xml
                                **/*.yml
                            
                        
                        
                            src/main/resources/
                            false
                            
                                **/*.xml
                                **/*.yml
                            
                        
                    
                
            
        
    
    

    이 플러그인은 간단한 복사 기능 외에도 Filtering 작업을 할 수 있습니다.
    Filtering Variables can be included in your resources. These variables, denoted by the ${...} delimiters, can come from the system properties, your project properties, from your filter resources and from the command line.
    리소스 파일에서 자신의 변수를 정의할 수 있습니다. 시스템 속성, 마븐 프로젝트 속성, 필터된 리소스 파일과 명령줄에서 나온 변수입니다.
    말하자면, 코피 자원 파일을 만들 때, 동시에 파일의 변수 (자리 차지 문자) 를 실제 값으로 바꿔 줍니다.여기는 #를 통해 변수 형식을 정합니다!다시 말하면 파일에서 # 시작과 끝의 문자열은 모두 바뀐다. (변수가 정의된 경우, 그렇지 않으면 그대로 유지된다.)
    여기에는 생명주기인 validate가 연결되어 있기 때문에 mvn validate -Plocal 명령을 직접 실행할 수 있습니다.얻은bootstrap.yml의 내용은 다음과 같습니다.
    spring:
        application:
            name: petstore
        profiles:
            # The commented value for `active` can be replaced with valid Spring profiles to load.
            # Otherwise, it will be filled in by maven when building the WAR file
            # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
            active: dev #     
    

    왜 마븐의properties에서spring만 정의했는지 처음 의문으로 돌아가자.profiles.active, 실행 mvn spring-boot:run -Plocal 할 때springboot에서 applicaiton-local.yml 프로필을 사용할 수 있습니까?
    마븐이 명령을 실행하기 전에copy-resources의 조작을 했기 때문에bootstrap.yml의 스프링.profiles.active는local로 바뀌었기 때문에springboot 응용 프로그램을 시작할 때spring을 사용합니다.profiles.active가 대표하는 값입니다. 여기가 local입니다. 그러면 활성화된 파일은 자연히 응용 프로그램-local입니다.yml.

    좋은 웹페이지 즐겨찾기