Spring Профили на уровне метода?
Я бы хотел ввести некоторые методы, которые выполняются только во время разработки.
Я думал, что могу использовать аннотацию Spring @Profile
здесь? Но как я могу применить эту аннотацию на уровне класса, так что этот метод вызывается только в том случае, если определенный профиль настроен в свойствах?
spring.profiles.active=dev
В качестве псевдокода возьмите следующее. Как это можно сделать?
class MyService {
void run() {
log();
}
@Profile("dev")
void log() {
//only during dev
}
}
Ответы
Ответ 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 на уровне метода)