欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot中的那些條件判斷的實現(xiàn)方法

 更新時間:2019年04月12日 11:26:34   作者:沈子平  
這篇文章主要介紹了Spring Boot中的那些條件判斷的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Spring Boot中的那些Conditional

spring boot中為我們提供了豐富的Conditional來讓我們得以非常方便的在項目中向容器中添加Bean。本文主要是對各個注解進行解釋并輔以代碼說明其用途。

所有ConditionalOnXXX的注解都可以放置在class或是method上,如果方式在class上,則會決定該class中所有的@Bean注解方法是否執(zhí)行。

@Conditional

下面其他的Conditional注解均是語法糖,可以通過下面的方法自定義ConditionalOnXXX

Conditional注解定義如下,接收實現(xiàn)Condition接口的class數(shù)組。

public @interface Conditional {
  Class<? extends Condition>[] value();
}

而Condition接口只有一個matchs方法,返回是否匹配的結(jié)果。

public interface Condition {
  boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

通過操作系統(tǒng)進行條件判斷,從而進行Bean配置。當(dāng)Window時,實例化Bill的Person對象,當(dāng)Linux時,實例化Linus的Person對象。

//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("當(dāng)前系統(tǒng)為:" + osName);
    Map<String, Person> map = applicationContext.getBeansOfType(Person.class);
    System.out.println(map);
  }
}

輸出的結(jié)果:

當(dāng)前系統(tǒng)為:Mac OS X
{linus=Person(name=Linus, age=48)}

@ConditionalOnBean & @ConditionalOnMissingBean

這兩個注解會對Bean容器中的Bean對象進行判斷,使用的例子是配置的時候,如果發(fā)現(xiàn)如果沒有Computer實例,則實例化一個備用電腦。

@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,Computer> map = applicationContext.getBeansOfType(Computer.class);
    System.out.println(map);
  }
}

修改BeanConfig,如果注釋掉第一個@Bean,會實例化備用電腦,否則就不會實例化備用電腦

@ConditionalOnClass & @ConditionalOnMissingClass

這個注解會判斷類路徑上是否有指定的類,一開始看到的時候比較困惑,類路徑上如果沒有指定的class,那編譯也通過不了啊...這個主要用于集成相同功能的第三方組件時用,只要類路徑上有該組件的類,就進行自動配置,比如spring boot web在自動配置視圖組件時,是用Velocity,還是Thymeleaf,或是freemaker時,使用的就是這種方式。

例子是兩套盔甲A(光明套裝)和B(暗黑套裝),如果A不在則配置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是武士,使用套裝進行戰(zhàn)斗

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Van {
  private Fighter fighter;
  public void fight(){
    fighter.fight();
  }
}

VanConfigA/B實例化武士

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

測試類,默認(rèn)情況,如果套裝AB都在類路徑上,兩套都會加載,A會設(shè)置為PRIMARY,如果在target class中將FightA.class刪除,則只會加載套裝B。

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

另外,嘗試將兩個VanConfigA/B合并,將注解ConditionalOnClass放到方法上,如果刪除一個套裝就會運行出錯。

@ConditionalOnExpress

依據(jù)表達(dá)式進行條件判斷,這個作用和@ConditionalOnProperty大部分情況可以通用,表達(dá)式更靈活一點,因為可以使用SpEL。例子中會判斷properties中test.enabled的值進行判斷。BeanConfig分別對布爾,字符串和數(shù)字三種類型進行判斷。數(shù)字嘗試了很多其他的方式均不行,比如直接使用==,貌似配置的屬性都會當(dāng)成字符串來處理。

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

@ConditionalOnProperty

適合對單個Property進行條件判斷,而上面的@ConditionalOnExpress適合面對較為復(fù)雜的情況,比如多個property的關(guān)聯(lián)比較。這個例子也給了三種基本類型的條件判斷,不過貌似均當(dāng)成字符串就可以...

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

  }
}

@ConditionalOnJava

可以通過java的版本進行判斷。

@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,TestBean> map = context.getBeansOfType(TestBean.class);
    System.out.println(map);
  }
}

@ConditionalOnResource

通過指定的資源文件是否存在進行條件判斷,比如判斷ehcache.properties來決定是否自動裝配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,TestBean> map = context.getBeansOfType(TestBean.class);
    System.out.println(map);
  }
}

@ConditionalOnSingleCandidate

這個還沒有想到應(yīng)用場景,條件通過的條件是:1 對應(yīng)的bean容器中只有一個 2.對應(yīng)的bean有多個,但是已經(jīng)制定了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,BeanA> map = context.getBeansOfType(BeanA.class);
    System.out.println(map);
    Map<String,BeanB> map2 = context.getBeansOfType(BeanB.class);
    System.out.println(map2);
  }
}

@ConditionalOnNotWebApplication & @ConditionalOnWebApplication

判斷當(dāng)前環(huán)境是否是Web應(yīng)用。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • mac下修改idea的jvm運行參數(shù)解決idea卡頓的情況

    mac下修改idea的jvm運行參數(shù)解決idea卡頓的情況

    這篇文章主要介紹了mac下修改idea的jvm運行參數(shù)解決idea卡頓的情況,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java微信公眾平臺開發(fā)(2) 微信服務(wù)器post消息體的接收

    Java微信公眾平臺開發(fā)(2) 微信服務(wù)器post消息體的接收

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺開發(fā)第二步,微信服務(wù)器post消息體的接收,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 全面了解Java中對于異常的捕捉方法

    全面了解Java中對于異常的捕捉方法

    這篇文章主要全面介紹了Java中對于異常的捕捉方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • java 實現(xiàn)數(shù)組擴容與縮容案例

    java 實現(xiàn)數(shù)組擴容與縮容案例

    這篇文章主要介紹了java 實現(xiàn)數(shù)組擴容與縮容案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • spring循環(huán)注入異常問題的解決方案

    spring循環(huán)注入異常問題的解決方案

    今天小編就為大家分享一篇關(guān)于spring循環(huán)注入異常問題的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java算法真題詳解運用單調(diào)棧

    Java算法真題詳解運用單調(diào)棧

    一般使用單調(diào)棧無非兩個方向,單調(diào)遞減,單調(diào)遞增。單調(diào)遞增棧:存進去的數(shù)據(jù)都是增加的,碰到減少的時候,這時就要進行操作了。單調(diào)遞減棧:存進去的數(shù)據(jù)都是減少的,碰到增加的時候,這時就要進行操作了,下面我們在真題中運用它
    2022-07-07
  • 淺談Java封裝、繼承、多態(tài)特性

    淺談Java封裝、繼承、多態(tài)特性

    大家好,本篇文章主要講的是淺談Java封裝、繼承、多態(tài)特性,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • java遞歸實現(xiàn)復(fù)制一個文件夾下所有文件功能

    java遞歸實現(xiàn)復(fù)制一個文件夾下所有文件功能

    這篇文章主要介紹了java遞歸實現(xiàn)復(fù)制一個文件夾下所有文件功能n次,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java中的數(shù)組復(fù)制(clone與arraycopy)代碼詳解

    Java中的數(shù)組復(fù)制(clone與arraycopy)代碼詳解

    這篇文章主要介紹了Java中的數(shù)組復(fù)制(clone與arraycopy)代碼詳解,本文并未全部介紹數(shù)組復(fù)制的幾種方式,僅對clone和copy的相關(guān)內(nèi)容進行了解析,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • JAVA實現(xiàn)異步調(diào)用實例代碼

    JAVA實現(xiàn)異步調(diào)用實例代碼

    在java平臺,實現(xiàn)異步調(diào)用的角色主要三種角色:調(diào)用者、取貨憑證、真實數(shù)據(jù)。本篇文章給大家介紹java實現(xiàn)異步調(diào)用實例代碼,需要的朋友可以參考下
    2015-09-09

最新評論