Le contenu de cet article est une introduction au jugement conditionnel dans Spring Boot (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Ces conditions dans Spring Boot
Spring Boot nous offre une multitude de conditions qui nous permettent d'ajouter des beans au conteneur dans le projet de manière très pratique. Cet article explique principalement chaque annotation et illustre son utilisation avec du code.
Toutes les annotations ConditionalOnXXX peuvent être placées sur une classe ou une méthode. Si la méthode est sur une classe, elle déterminera si toutes les méthodes annotées @Bean de la classe sont exécutées.
Les autres annotations conditionnelles ci-dessous sont du sucre syntaxique. Vous pouvez personnaliser ConditionalOnXXX via la méthode suivante.
L'annotation conditionnelle est définie comme suit, recevant le tableau de classe qui implémente le. Interface de conditions.
public @interface Conditional { Class extends Condition>[] value(); }
L'interface Condition n'a qu'une seule méthode matches, qui renvoie le résultat de la correspondance.
public interface Condition { boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
Configurez les conditions via le système d'exploitation pour configurer Bean. Lorsque Window est utilisé, l'objet Person de Bill est instancié, et lorsque Linux est utilisé, l'objet Person de Linus est instancié.
//LinuxCondition,为方便起见,去掉判断代码,直接返回true了 public class LinuxCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { return true; } }
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了 public class WindowsCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { return false; } }
@Data @ToString @AllArgsConstructor @NoArgsConstructor public class Person { private String name; private Integer age; }
//配置类 @Configuration public class BeanConfig { @Bean(name = "bill") @Conditional({WindowsCondition.class}) public Person person1(){ return new Person("Bill Gates",62); } @Bean("linus") @Conditional({LinuxCondition.class}) public Person person2(){ return new Person("Linus",48); } }
public class AppTest { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test(){ String osName = applicationContext.getEnvironment().getProperty("os.name"); System.out.println("当前系统为:" + osName); Map<string> map = applicationContext.getBeansOfType(Person.class); System.out.println(map); } }</string>
Résultat de sortie :
Le système actuel est : Mac OS X
{linus=Person(name=Linus, age=48)}
Ces deux annotations jugeront l'objet Bean dans le conteneur Bean. L'exemple utilisé est lors de la configuration s'il s'avère qu'il n'y en a pas. Instance d'ordinateur, instanciez un ordinateur de sauvegarde.
@Data @AllArgsConstructor @ToString public class Computer { private String name; }
@Configuration public class BeanConfig { @Bean(name = "notebookPC") public Computer computer1(){ return new Computer("笔记本电脑"); } @ConditionalOnMissingBean(Computer.class) @Bean("reservePC") public Computer computer2(){ return new Computer("备用电脑"); } }
public class TestApp { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test1(){ Map<string> map = applicationContext.getBeansOfType(Computer.class); System.out.println(map); } }</string>
Modifiez BeanConfig, si vous commentez le premier @Bean, l'ordinateur de sauvegarde sera instancié, sinon l'ordinateur de sauvegarde ne sera pas instancié
Cette annotation déterminera s'il y a une classe spécifiée sur le chemin de classe. J'étais confus lorsque je l'ai vue pour la première fois. S'il n'y a pas de classe spécifiée sur le chemin de classe, la compilation ne réussira pas. .. Ceci est principalement utilisé lors de l'intégration de composants tiers avec la même fonction. Tant qu'il y a une classe du composant sur le chemin de classe, elle sera automatiquement configurée. Par exemple, lorsque Spring Boot Web configure automatiquement le. composant view, qu'il utilise Velocity, Thymeleaf ou freemaker, c'est la méthode utilisée.
L'exemple est deux ensembles d'armures A (combinaison légère) et B (combinaison sombre). Si A n'est pas présent, configurez B.
public interface Fighter { void fight(); } public class FighterA implements Fighter { @Override public void fight() { System.out.println("使用光明套装"); } } public class FighterB implements Fighter { @Override public void fight() { System.out.println("使用暗黑套装"); } }
Van est un samouraï et utilise la combinaison pour combattre
@Data @AllArgsConstructor @NoArgsConstructor public class Van { private Fighter fighter; public void fight(){ fighter.fight(); } }
VanConfigA/B instancie le samouraï
@Configuration @ConditionalOnClass({FighterA.class}) public class VanConfigA { @Primary @Bean public Van vanA(){ return new Van(new FighterA()); } } @Configuration @ConditionalOnClass({FighterB.class}) public class VanConfigB { @Bean public Van vanB(){ return new Van(new FighterB()); } }
Classe de test, par défaut, si suit AB Les deux sont sur le chemin de classe, les deux ensembles seront chargés et A sera défini sur PRIMARY. Si FightA.class est supprimé dans la classe cible, seul l'ensemble B sera chargé.
@SpringBootApplication public class TestApp implements CommandLineRunner { @Autowired private Van van; public static void main(String[] args) { SpringApplication.run(TestApp.class, args); } @Override public void run(String... args) throws Exception { //do something van.fight(); } }
De plus, essayez de fusionner les deux VanConfigA/B et mettez l'annotation ConditionalOnClass sur la méthode. Si vous supprimez un package, une erreur se produira.
Jugement conditionnel basé sur des expressions. Cette fonction peut être utilisée dans la plupart des cas avec @ConditionalOnProperty L'expression est plus flexible car SpEL peut être utilisée. Dans l'exemple, la valeur de test.enabled dans les propriétés sera jugée. BeanConfig juge respectivement trois types de booléens, de chaînes et de nombres. J'ai essayé de nombreuses autres méthodes mais aucune ne fonctionne, comme l'utilisation directe de ==. Il semble que les attributs configurés seront traités comme des chaînes.
@Data public class TestBean { private String name; }
@Configuration @ConditionalOnExpression("#{${test.enabled:true} }") //@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')") //@ConditionalOnExpression("new Integer('${test.account}')==1") public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean("我是美猴王"); } }
@SpringBootApplication public class TestAppCommand implements CommandLineRunner { @Autowired private TestBean testBean; public static void main(String[] args) { SpringApplication.run(TestAppCommand.class, args); } @Override public void run(String... args) throws Exception { System.out.println(testBean.getName()); } }
convient au jugement conditionnel sur une seule propriété, tandis que le @ConditionalOnExpress ci-dessus convient à des situations plus complexes, telles que l'association de plusieurs propriétés Comparez. Cet exemple donne également trois types de base de jugements conditionnels, mais il semble qu'ils puissent tous être traités comme des chaînes...
@Data @AllArgsConstructor @NoArgsConstructor public class TestBean { private String name; }
@Configuration @ConditionalOnProperty(prefix = "test", name="enabled", havingValue = "true",matchIfMissing = false) //@ConditionalOnProperty(prefix = "test", name="account", havingValue = "1",matchIfMissing = false) //@ConditionalOnProperty(prefix = "test", name="name1", havingValue = "zz",matchIfMissing = false) public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean("我是美猴王"); } }
@SpringBootApplication public class TestAppCommand implements CommandLineRunner { @Autowired private TestBean testBean; public static void main(String[] args) { SpringApplication.run(TestAppCommand.class, args); } @Override public void run(String... args) throws Exception { System.out.println(testBean.getName()); } }
Vous pouvez utilisez la version Java pour juger.
@Data public class TestBean { }
@Configuration @ConditionalOnJava(JavaVersion.EIGHT) public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean(); } }
public class TestApp { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test(){ Map<string> map = context.getBeansOfType(TestBean.class); System.out.println(map); } }</string>
Effectuer un jugement conditionnel selon que le fichier de ressources spécifié existe, par exemple en jugeant ehcache.properties pour déterminer s'il faut assembler automatiquement le composant ehcache .
@Data public class TestBean { }
@Configuration @ConditionalOnResource(resources = "classpath:application.yml") public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean(); } }
public class TestApp { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test(){ Map<string> map = context.getBeansOfType(TestBean.class); System.out.println(map); } }</string>
Je n'ai pas encore pensé au scénario d'application. Les conditions pour réussir la condition sont : 1. Il n'y a qu'un seul bean correspondant. conteneur 2. Le bean correspondant a Multiple, mais PRIMARY a été formulé. Dans l'exemple, lors de l'assemblage de BeanB, vous devez vérifier l'état de l'assemblage de BeanA, donc BeanBConfig doit être classé après BeanAConfig. Vous pouvez modifier BeanAConfig et supprimer l'annotation @Primary, ou supprimer les trois annotations @Bean, et BeanB ne le sera pas. instancié.
@Data @AllArgsConstructor @NoArgsConstructor public class BeanA { private String name; }
@Configuration public class BeanAConfig { @Bean @Primary public BeanA bean1(){ return new BeanA("bean1"); } @Bean(autowireCandidate = false) public BeanA bean2(){ return new BeanA("bean2"); } //@Bean(autowireCandidate = false) public BeanA bean3(){ return new BeanA("bean3"); } }
@Data public class BeanB { }
@Configuration @AutoConfigureAfter(BeanAConfig.class) @ConditionalOnSingleCandidate(BeanA.class) public class BeanBConfig { @Bean public BeanB targetBean(){ return new BeanB(); } }
public class TestApp { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class); @Test public void test(){ Map<string> map = context.getBeansOfType(BeanA.class); System.out.println(map); Map<string> map2 = context.getBeansOfType(BeanB.class); System.out.println(map2); } }</string></string>
Déterminez si l'environnement actuel est une application Web.
Ces conditions dans le jugement Spring Boot
Ces conditions dans Spring BootSpring Boot nous offre une multitude de conditions pour nous permettre de les utiliser très facilement dans le projet Ajouter des beans au conteneur. Cet article explique principalement chaque annotation et illustre son utilisation avec du code. Toutes les annotations ConditionalOnXXX peuvent être placées sur une classe ou une méthode. Si la méthode est sur une classe, elle déterminera si toutes les méthodes annotées @Bean de la classe sont exécutées. @ConditionalLes autres annotations conditionnelles ci-dessous sont du sucre syntaxique. Vous pouvez personnaliser ConditionalOnXXX via la méthode suivante.L'annotation conditionnelle est définie comme suit, recevant le tableau de classe qui implémente le. Interface de conditions.
L'interface Condition n'a qu'une seule méthode matches, qui renvoie le résultat de la correspondance.
Configurez les conditions via le système d'exploitation pour configurer Bean. Lorsque Window est utilisé, l'objet Person de Bill est instancié, et lorsque Linux est utilisé, l'objet Person de Linus est instancié.Le système actuel est : Mac OS X
{linus=Person(name=Linus, age=48)}
public @interface Conditional { Class extends Condition>[] value(); }@ConditionalOnBean & @ConditionalOnMissingBeanCes deux annotations jugeront l'objet Bean dans le conteneur Bean. L'exemple utilisé est lors de la configuration s'il s'avère qu'il n'y en a pas. Instance d'ordinateur, instanciez un ordinateur de sauvegarde.
public interface Condition { boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
//LinuxCondition,为方便起见,去掉判断代码,直接返回true了 public class LinuxCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { return true; } }
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了 public class WindowsCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { return false; } }Modifiez BeanConfig, si vous commentez le premier @Bean, l'ordinateur de sauvegarde sera instancié, sinon l'ordinateur de sauvegarde ne sera pas instancié
@Data @ToString @AllArgsConstructor @NoArgsConstructor public class Person { private String name; private Integer age; }
//配置类 @Configuration public class BeanConfig { @Bean(name = "bill") @Conditional({WindowsCondition.class}) public Person person1(){ return new Person("Bill Gates",62); } @Bean("linus") @Conditional({LinuxCondition.class}) public Person person2(){ return new Person("Linus",48); } }@ConditionalOnClass & @ConditionalOnMissingClass
public class AppTest { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test(){ String osName = applicationContext.getEnvironment().getProperty("os.name"); System.out.println("当前系统为:" + osName); Map<string> map = applicationContext.getBeansOfType(Person.class); System.out.println(map); } }</string>
Cette annotation déterminera s'il y a une classe spécifiée sur le chemin de classe. J'étais confus lorsque je l'ai vue pour la première fois. S'il n'y a pas de classe spécifiée sur le chemin de classe, la compilation ne réussira pas. .. Ceci est principalement utilisé lors de l'intégration de composants tiers avec la même fonction. Tant qu'il y a une classe du composant sur le chemin de classe, elle sera automatiquement configurée. Par exemple, lorsque Spring Boot Web configure automatiquement le. composant view, qu'il utilise Velocity, Thymeleaf ou freemaker, c'est la méthode utilisée.
L'exemple est deux ensembles d'armures A (combinaison légère) et B (combinaison sombre). Si A n'est pas présent, configurez B.Van est un samouraï et utilise la combinaison pour combattre
VanConfigA/B instancie le samouraï
@Data @AllArgsConstructor @ToString public class Computer { private String name; }
@Configuration public class BeanConfig { @Bean(name = "notebookPC") public Computer computer1(){ return new Computer("笔记本电脑"); } @ConditionalOnMissingBean(Computer.class) @Bean("reservePC") public Computer computer2(){ return new Computer("备用电脑"); } }Classe de test, par défaut, si suit AB Les deux sont sur le chemin de classe, les deux ensembles seront chargés et A sera défini sur PRIMARY. Si FightA.class est supprimé dans la classe cible, seul l'ensemble B sera chargé.
public class TestApp { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test1(){ Map<string> map = applicationContext.getBeansOfType(Computer.class); System.out.println(map); } }</string>De plus, essayez de fusionner les deux VanConfigA/B et mettez l'annotation ConditionalOnClass sur la méthode. Si vous supprimez un package, une erreur se produira. @ConditionalOnExpress
Jugement conditionnel basé sur des expressions. Cette fonction peut être utilisée dans la plupart des cas avec @ConditionalOnProperty L'expression est plus flexible car SpEL peut être utilisée. Dans l'exemple, la valeur de test.enabled dans les propriétés sera jugée. BeanConfig juge respectivement trois types de booléens, de chaînes et de nombres. J'ai essayé de nombreuses autres méthodes mais aucune ne fonctionne, comme l'utilisation directe de ==. Il semble que les attributs configurés seront traités comme des chaînes.
public interface Fighter { void fight(); } public class FighterA implements Fighter { @Override public void fight() { System.out.println("使用光明套装"); } } public class FighterB implements Fighter { @Override public void fight() { System.out.println("使用暗黑套装"); } }
@Data @AllArgsConstructor @NoArgsConstructor public class Van { private Fighter fighter; public void fight(){ fighter.fight(); } }@ConditionalOnProperty convient au jugement conditionnel sur une seule propriété, tandis que le @ConditionalOnExpress ci-dessus convient à des situations plus complexes, telles que l'association de plusieurs propriétés Comparez. Cet exemple donne également trois types de base de jugements conditionnels, mais il semble qu'ils puissent tous être traités comme des chaînes...
@Configuration @ConditionalOnClass({FighterA.class}) public class VanConfigA { @Primary @Bean public Van vanA(){ return new Van(new FighterA()); } } @Configuration @ConditionalOnClass({FighterB.class}) public class VanConfigB { @Bean public Van vanB(){ return new Van(new FighterB()); } }
@SpringBootApplication public class TestApp implements CommandLineRunner { @Autowired private Van van; public static void main(String[] args) { SpringApplication.run(TestApp.class, args); } @Override public void run(String... args) throws Exception { //do something van.fight(); } }
@ConditionalOnJava
@Data public class TestBean { private String name; }
@Configuration @ConditionalOnExpression("#{${test.enabled:true} }") //@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')") //@ConditionalOnExpression("new Integer('${test.account}')==1") public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean("我是美猴王"); } }@ConditionalOnResource
@SpringBootApplication public class TestAppCommand implements CommandLineRunner { @Autowired private TestBean testBean; public static void main(String[] args) { SpringApplication.run(TestAppCommand.class, args); } @Override public void run(String... args) throws Exception { System.out.println(testBean.getName()); } }
@Data public class TestBean { }
@Configuration @ConditionalOnResource(resources = "classpath:application.yml") public class BeanConfig { @Bean public TestBean testBean(){ return new TestBean(); } }
public class TestApp { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); @Test public void test(){ Map<string> map = context.getBeansOfType(TestBean.class); System.out.println(map); } }</string>
这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了PRIMARY。例子中,BeanB装配的时候需要看BeanA的装配情况,所以BeanBConfig要排在BeanAConfig之后.可以修改BeanAConfig,将@Primary注解去掉,或者把三个@Bean注解去掉,BeanB就不会实例化了。
@Data @AllArgsConstructor @NoArgsConstructor public class BeanA { private String name; }
@Configuration public class BeanAConfig { @Bean @Primary public BeanA bean1(){ return new BeanA("bean1"); } @Bean(autowireCandidate = false) public BeanA bean2(){ return new BeanA("bean2"); } //@Bean(autowireCandidate = false) public BeanA bean3(){ return new BeanA("bean3"); } }
@Data public class BeanB { }
@Configuration @AutoConfigureAfter(BeanAConfig.class) @ConditionalOnSingleCandidate(BeanA.class) public class BeanBConfig { @Bean public BeanB targetBean(){ return new BeanB(); } }
public class TestApp { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class); @Test public void test(){ Map<string> map = context.getBeansOfType(BeanA.class); System.out.println(map); Map<string> map2 = context.getBeansOfType(BeanB.class); System.out.println(map2); } }</string></string>
判断当前环境是否是Web应用。
评论
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!