Je voudrais présenter quelques méthodes qui ne sont exécutées que pendant le développement.
J'ai pensé que je pourrais utiliser Spring @Profile
annotation ici? Mais comment puis-je appliquer cette annotation au niveau de la classe, afin que cette méthode ne soit invoquée que si le profil spécifique est configuré dans les propriétés?
spring.profiles.active=dev
Prenez ce qui suit comme pseudocode. Comment cela peut-il être fait?
class MyService {
void run() {
log();
}
@Profile("dev")
void log() {
//only during dev
}
}
COMME vous pouvez le lire http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html
L'annotation @Profile peut être utilisée de l'une des manières suivantes:
en tant qu'annotation de niveau type sur toute classe annotée directement ou indirectement avec @Component, y compris les classes @Configuration en tant que méta-annotation, dans le but de composer des annotations de stéréotypes personnalisés Si une classe @Configuration est marqué avec @Profile, toutes les méthodes @Bean et les annotations @Import associées à cette classe seront ignorées à moins qu'un ou plusieurs des profils spécifiés ne soient actifs. Ceci est très similaire au comportement de Spring XML: si l'attribut profile de l'élément beans est fourni par exemple, l'élément beans ne sera pas analysé à moins que les profils 'p1' et/ou 'p2' n'aient été activés. De même, si une classe @Component ou @Configuration est marquée avec @Profile ({"p1", "p2"}), cette classe ne sera pas enregistrée/traitée à moins que les profils 'p1' et/ou 'p2' n'aient été activés.
Ainsi, une annotation @Profile sur une classe, s'applique à toutes ses méthodes et à ses importations. Pas à la classe.
Ce que vous essayez de faire pourrait probablement être réalisé en ayant deux classes qui implémentent la même interface et en injectant l'une ou l'autre en fonction du profil. Jetez un œil à la réponse à cette question.
injection de dépendances basée sur des annotations qui gère différents environnements
Pour les futurs lecteurs qui ne veulent pas avoir plusieurs @Beans
annoté avec @Profile
, cela pourrait aussi être une solution:
class MyService {
@Autowired
Environment env;
void run() {
if (Arrays.asList(env.getActiveProfiles()).contains("dev")) {
log();
}
}
void log() {
//only during dev
}
}
Je voulais juste ajouter que réponse disant que c'est possible avec le ressort actuel au niveau de la méthode est manifestement faux. L'utilisation de @Profile sur les méthodes en général ne fonctionnera pas - les seules méthodes sur lesquelles elle fonctionnera sont dans la classe @Configuration avec l'annotation @Bean dessus.
Je lance un test rapide avec Spring 4.2.4, où on a vu que
Classe de test:
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();
}
}
@Profile
peut être utilisé avec la méthode et avec Java Based Configuration
par exemple. horodatage DB distinct pour PostgreSQL (LocalDateTime) et pour HSQLDB (avant 2.4.0 Timestamp):
@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;
}
Jetez également un œil à exemple Spring Profiles : 3. Plus… (exemple Spring @Profile au niveau de la méthode)
Possible en 4.1
L'annotation @Profile peut être utilisée de l'une des manières suivantes:
en tant qu'annotation de niveau type sur n'importe quelle classe annotée directement ou indirectement avec @Component, y compris les classes @Configuration. En tant que méta-annotation, dans le but de composer des annotations de stéréotypes personnalisées. En tant qu'annotation au niveau de la méthode sur n'importe quelle méthode @Bean