source

방법 수준의 스프링 프로파일?

factcode 2023. 8. 7. 23:10
반응형

방법 수준의 스프링 프로파일?

개발 중에만 실행되는 몇 가지 방법을 소개하고자 합니다.

제 생각에 제가까운...Spring @Profile주석을 여기에 추가하시겠습니까?그러나 클래스 수준에서 이 주석을 적용하여 특정 프로파일이 속성에 구성된 경우에만 이 메서드를 호출하려면 어떻게 해야 합니까?

spring.profiles.active=dev

다음을 유사 코드로 간주합니다.이것이 어떻게 행해지는가?

class MyService {

    void run() { 
       log();
    }

    @Profile("dev")
    void log() {
       //only during dev
    }
}

개를 .@Beans로주을로 주석을 .@Profile이것도 해결책이 될 수 있습니다.

class MyService {

   @Autowired
   Environment env;

   void run() { 
      if (Arrays.asList(env.getActiveProfiles()).contains("dev")) {
         log();
      }
   }

   void log() {
      //only during dev
   }
}

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html 에서 읽을 수 있는 것처럼

@Profile 주석은 다음과 같은 방식으로 사용할 수 있습니다.

사용자 정의 고정관념 주석을 구성하기 위해 @Configuration 클래스를 메타 주석으로 포함하여 @Component가 직접 또는 간접적으로 주석이 달린 클래스에 대한 유형 수준 주석 @Configuration 클래스가 @Profile로 표시된 경우, 지정된 프로필이 하나 이상 활성화되지 않은 경우 해당 클래스와 관련된 모든 @Bean 메서드 및 @Import 주석은 바이패스됩니다.이것은 Spring XML의 동작과 매우 유사합니다. 예를 들어, 콩 요소의 프로필 속성이 제공되면 'p1' 및/또는 'p2' 프로파일이 활성화되지 않으면 콩 요소가 구문 분석되지 않습니다.마찬가지로 @Component 또는 @Configuration 클래스에 @Profile({"p1", "p2"})이 표시되어 있으면 프로파일 'p1' 및/또는 'p2'이 활성화되지 않으면 해당 클래스가 등록/처리되지 않습니다.

따라서 클래스의 @Profile 주석은 클래스의 모든 메서드 및 가져오기에 적용됩니다.수업에는 안 됩니다.

당신이 하려는 것은 아마도 동일한 인터페이스를 구현하는 두 개의 클래스를 가지고 프로파일에 따라 하나 또는 다른 하나를 주입함으로써 달성될 수 있을 것입니다.이 질문에 대한 답을 보세요.

다양한 환경을 처리하는 주석 기반 종속성 주입

@Profile메서드 및 Java 기반 구성과 함께 사용할 수 있습니다.

예: PostgreSQL(LocalDateTime) 및 HSQLDB(2.4.0 Timestamp 이전 버전)에 대한 별도의 DB 타임스탬프:

@Autowired
private Function<LocalDateTime, T> dateTimeExtractor;

@Bean
@Profile("hsqldb")
public Function<LocalDateTime, Timestamp> getTimestamp() {
    return Timestamp::valueOf;
}

@Bean
@Profile("postgres")
public Function<LocalDateTime, LocalDateTime> getLocalDateTime() {
    return dt -> dt;
}

스프링 프로파일3도 살펴봅니다.추가...(표본 스프링 @방법 수준의 프로파일)

방법 수준의 현재 봄으로 이것이 가능하다고 말하는 답변을 추가하고 싶은 것은 명백히 잘못된 것입니다.일반적으로 메서드에 @Profile을 사용하면 작동하지 않습니다. 이 메서드에서 작동하는 유일한 메서드는 @Configuration 클래스에 @Bean 주석이 있는 것입니다.

Spring 4.2.4를 사용하여 빠른 테스트를 실행합니다. 여기서 Spring 4.2.4는

  • @@Configuration 클래스의 프로파일 빈 생성 메서드 작업
  • @빈 메서드의 프로필이 작동하지 않습니다(그리고 작동할 것으로 예상되지 않습니다 - 문서가 약간 모호합니다).
  • 클래스 수준 @Profile은 구성 클래스에서 bean 정의와 동일한 컨텍스트에 있거나 context-scan이 사용되는 경우에만 작동합니다.
  • env.acceptsProfiles("profile"), Arrays.asList(env.getActiveProfiles()).contains("profile") 작업

테스트 클래스:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Arrays;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ProfileTest.ProfileTestConfiguration.class })
@ActiveProfiles("test")
public class ProfileTest {
    static class SomeClass {}
    static class OtherClass {}
    static class ThirdClass {
        @Profile("test")
        public void method() {}
    }
    static class FourthClass {
        @Profile("!test")
        public void method() {}
    }

    static class ProfileTestConfiguration {
        @Bean
        @Profile("test")
        SomeClass someClass() {
            return new SomeClass();
        }
        @Bean
        @Profile("!test")
        OtherClass otherClass() {
            return new OtherClass();
        }
        @Bean
        ThirdClass thirdClass() {
            return new ThirdClass();
        }
        @Bean
        FourthClass fourthClass() {
            return new FourthClass();
        }
    }

    @Autowired
    ApplicationContext context;

    @Test
    public void testProfileAnnotationIncludeClass() {
        context.getBean(SomeClass.class);
    }
    @Test(expected = NoSuchBeanDefinitionException.class)
    public void testProfileAnnotationExcludeClass() {
        context.getBean(OtherClass.class);
    }
    @Test
    public void testProfileAnnotationIncludeMethod() {
        context.getBean(ThirdClass.class).method();
    }
    @Test(expected = Exception.class)  // fails
    public void testProfileAnnotationExcludeMethod() {
        context.getBean(FourthClass.class).method();
    }
}

4.1에서 가능

@Profile 주석은 다음과 같은 방식으로 사용할 수 있습니다.

@Configuration 클래스를 포함하여 @Component로 직접 또는 간접적으로 주석이 달린 모든 클래스에 대한 유형 수준 주석으로 사용됩니다.메타 주석으로서, 사용자 정의 고정관념 주석을 작성하기 위한 목적으로.모든 @Bean 방법에 대한 방법 수준 주석으로 사용

http://docs.spring.io/spring/docs/4.1.x/javadoc-api/org/springframework/context/annotation/Profile.html

@Profile그것에 사용될 수는 없지만, 당신은 당신 자신의 코드를 작성하는 것이 좋을 것입니다.@RunOnProfile주석 및 측면방법은 다음과 같습니다.

@RunOnProfile({"dev", "uat"})
public void doSomething() {
    log.info("I'm doing something on dev and uat");
}

또는

@RunOnProfile("!prod")
public void doSomething() {
    log.info("I'm doing something on profile other than prod");
}

다음은 다음과 같은 코드입니다.@RunOnProfile주석 및 측면:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RunOnProfile {
    String[] value();

    @Aspect
    @Configuration
    class RunOnProfileAspect {

        @Autowired
        Environment env;

        @Around("@annotation(runOnProfile)")
        public Object around(ProceedingJoinPoint joinPoint, RunOnProfile runOnProfile) throws Throwable {
            if (env.acceptsProfiles(runOnProfile.value()))
                return joinPoint.proceed();
            return null;
        }
    }
}

참고 1: 만약 당신이 그 대가로 무엇인가를 기대하고 프로파일이 적용되지 않는다면, 당신은 얻을 것입니다.null.

참고 2: 이는 다른 스프링 측면과 마찬가지로 작동합니다.bean 프록시를 시작하려면 auto-wired bean 메서드를 호출해야 합니다.즉, 다른 클래스 메소드에서 메소드를 직접 호출할 수 없습니다.원하는 경우 클래스에서 구성 요소를 자동으로 연결하고 호출해야 합니다.self.doSomething().

승인 프로파일(프로파일) 사용

class Test {

  @Autowired
  Environment env

  public void method1(){
     if(env.acceptsProfiles(Profiles.of("dev")){
        //invoke method
        doStuff();
     }
  }
}

환경 프로필을 사용하면 다음과 같은 작업을 수행할 수 있습니다.

class MyClass {

   @Autowired
   Environment env;

   void methodA() { 
      if (env.acceptsProfiles(Profiles.of("dev"))) {
         methodB();
      }
   }

   void methodB() {
      // when profile is 'dev'
   }
}

Profiles.of논리식과 함께 사용할 수 있습니다.

정적 프로파일(문자열...프로파일) 지정된 프로파일 문자열과 일치하는지 확인하는 새 프로파일 인스턴스를 만듭니다.반환된 인스턴스는 지정된 프로파일 문자열 중 하나가 일치하는 경우 일치합니다.

프로파일 문자열에는 단순 프로파일 이름(예: "production") 또는 프로파일 식을 포함할 수 있습니다.프로파일 표현식을 사용하면 프로덕션 및 클라우드와 같은 보다 복잡한 프로파일 논리를 표현할 수 있습니다.

프로필 식에서 지원되는 연산자는 다음과 같습니다.

- 프로파일의 논리가 아닌 논리와 프로파일의 논리 | - 논리 또는 프로파일의 논리 괄호를 사용하지 않고 & 연산자와 | 연산자를 혼합할 수 없음을 유의하십시오.예를 들어 "a & b | c"는 올바른 표현식이 아닙니다. "(a & b) | c" 또는 "a & (b | c)"로 표현되어야 합니다.

언급URL : https://stackoverflow.com/questions/22349120/spring-profiles-on-method-level

반응형