Подтвердить что ты не робот

Spring Профили на уровне метода?

Я бы хотел ввести некоторые методы, которые выполняются только во время разработки.

Я думал, что могу использовать аннотацию Spring @Profile здесь? Но как я могу применить эту аннотацию на уровне класса, так что этот метод вызывается только в том случае, если определенный профиль настроен в свойствах?

spring.profiles.active=dev

В качестве псевдокода возьмите следующее. Как это можно сделать?

class MyService {

    void run() { 
       log();
    }

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

Ответ 1

AS вы можете читать на http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html

Аннотацию @Profile можно использовать любым из следующих способов:

в качестве аннотации на уровне уровня для любого класса прямо или косвенно аннотируется с @Component, включая классы @Configuration как мета-аннотации, с целью составления пользовательского стереотипа аннотации Если класс @Configuration помечен как @Profile, все методы @Bean и аннотации @Import, связанные с этим классом будет обходить, если только один или несколько указанных профилей активны.Это очень похоже на поведение в Spring XML: если профиль атрибут элемента beans предоставляется, например, элемент beans не будет анализироваться, если только профили 'p1' и/или 'p2' активированы. Аналогичным образом, если @Component или Класс @Configuration помечен @Profile ({ "p1", "p2" }), этот класс не будут зарегистрированы/обработаны, если профили "p1" и/или "p2" не будут был активирован.

Итак, аннотация @Profile для класса, применяется ко всем его методам и импорту. Не для класса.

То, что вы пытаетесь сделать, возможно, может быть достигнуто за счет того, что два класса реализуют один и тот же интерфейс и вводят тот или иной в зависимости от профиля. Взгляните на ответ на этот вопрос.

Включение зависимостей, зависящих от аннотаций, которые обрабатывают разные среды

Ответ 2

Для будущих читателей, которые не хотят иметь несколько @Beans, аннотированных с помощью @Profile, это также может быть решением:

class MyService {

   @Autowired
   Environment env;

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

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

Ответ 3

Возможно в 4.1

Аннотацию @Profile можно использовать любым из следующих способов:

в качестве аннотации на уровне уровня для любого класса прямо или косвенно аннотируется с @Component, включая классы @Configuration. Как мета-аннотации, с целью составления пользовательского стереотипа аннотаций. В качестве аннотации уровня метода для любого метода @Bean

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

Ответ 4

Просто хотел добавить, что ответ, говорящий, что это возможно с текущим spring на уровне метода, вопиюще неверно. Использование @Profile в методах вообще не будет работать - единственные методы, с которыми он будет работать, находятся в классе @Configuration с аннотацией @ Bean.

Я провел быстрый тест с spring 4.2.4, где было видно, что

  • @Profile в классе @Configuration bean работают методы создания
  • @Profile в методах bean не работает (и не ожидается, что работа - документы немного неоднозначны)
  • Класс-класс @Profile работает тогда и только тогда, когда он используется в том же контексте, что и определение bean, в классе конфигурации или при использовании контекстного сканирования, там
  • env.acceptsProfiles( "profile" ), Arrays.asList(env.getActiveProfiles()) содержит ( "профиль" ) работает

Класс тестирования:

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();
    }
}

Ответ 5

@Profile может использоваться с методом и Конфигурация на Java

например. отдельную временную метку DB для PostgreSQL (LocalDateTime) и для HSQLDB (до отметки времени 2.4.0):

@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;
}

Посмотрите также на Spring Пример профилей: 3. Подробнее... (образец Spring @Profile на уровне метода)