精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringBoot一個非常強大的數據綁定類

開發 前端
本篇文章將介紹Spring Boot中一個非常強大且十分重要的類Binder,該類可以將外部配置文件的屬性值綁定到Spring Boot應用程序中的Java對象上。

環境:SpringBoot3.2.5

1. 簡介

本篇文章將介紹Spring Boot中一個非常強大且十分重要的類Binder,該類可以將外部配置文件的屬性值綁定到Spring Boot應用程序中的Java對象上。在Spring Boot中,通常使用@ConfigurationProperties注解來指定外部配置文件中的屬性前綴,并使用Binder的bind方法將配置值綁定到Java對象上。這樣,Spring Boot應用程序可以方便地讀取和使用配置文件中的屬性配置。

2. 實戰案例

2.1 準備綁定對象

public class Person {
  private Integer age ;
  private String name ;
  // getter, setter
}

配置文件中添加配置屬性

pack:
  person:
   age: 20
   name: 張三

測試綁定組件

@Component
public class BinderComponent implements InitializingBean {
  private final Environment env ;
  // 注入該對象是為了后面我們方便注冊自定義數據類型轉換
  private final ConversionService conviersionService ;
  public BinderComponent(Environment env, 
    ConversionService conviersionService) {
    this.env = env ;
    this.conviersionService = conviersionService ;
  }
  public void afterPropertiesSet() throws Exception {
    // 綁定測試都將在這里完成
  }
}

后續案例都將基于上面的環境

2.2 基礎綁定

// 這里的pack.person是配置文件中的前綴
BindResult<Person> result = Binder.get(env).bind("pack.person", Person.class) ;
Person person = result.get() ;
System.out.println(person) ;

在該示例中,配置文件中的age屬性能正確的轉換為Integer。為什么能進行數據類型轉換?因為內部(調用Binder#get(env)時)會添加TypeConverterConversionService和ApplicationConversionService兩個類型轉換器。

2.3 自定義數據類型轉換

給Person添加Date類型的字段,如下:

public class Person {
  private Integer age ;
  private String name ;
  private Date birthday ;
  // getter, setter
}
// 配置文件中添加birthday屬性
pack:
  person:
    birthday: 2000-01-01

在此執行上面2.2中代碼,程序拋出了如下異常

圖片圖片

默認的數據類型轉換器是沒有String到Date轉換功能。我們需要添加自定義的類型轉換,如下自定義類型轉換器:

@Configuration
public class DataTypeConvertConfig implements WebMvcConfigurer {
  @Override
  public void addFormatters(FormatterRegistry registry) {
    registry.addConverter(new Converter<String, Date>() {
      @Override
      public Date convert(String source) {
        try {
          return new SimpleDateFormat("yyyy-MM-dd").parse(source) ;
        } catch (ParseException e) {
          throw new RuntimeException(e) ;
        }
      }
    });
  }
}

修改數據綁定方式

Iterable<ConfigurationPropertySource> propertySources = ConfigurationPropertySources.get(env) ;
// 不使用默認的類型轉換服務,使用自定義(還是自動配置的,只是添加了我們自定義的)
Binder binder = new Binder(propertySources, null, conviersionService) ;
Person result = binder.bindOrCreate("pack.person", Person.class) ;
System.out.println(result) ;

這次成功輸出結果。

圖片

2.4 數據綁定回調

我們還可以為Binder執行綁定時,傳入回調句柄,這樣在數據綁定的各個階段都可以進行相應的處理,如下示例:

Iterable<ConfigurationPropertySource> propertySources = ConfigurationPropertySources.get(env) ;
Binder binder = new Binder(propertySources, null, conviersionService) ;
Person result = binder.bindOrCreate("pack.person", Bindable.of(Person.class), new BindHandler() {
  @Override
  public <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {
    System.out.printf("準備進行數據綁定:【%s】%n", name) ;
    return target ;
  }
  @Override
  public Object onSuccess(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) {
    System.out.printf("對象綁定成功:【%s】%n", result) ;
    return result ;
  }
  @Override
  public Object onCreate(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) {
    System.out.printf("準備創建綁定對象:【%s】%n", result) ;
    return result ;
  }
  @Override
  public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Exception error)
      throws Exception {
    System.out.printf("數據綁定失敗:【%s】%n", error.getMessage()) ;
    return BindHandler.super.onFailure(name, target, context, error);
  }
  @Override
  public void onFinish(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result)
      throws Exception {
    System.out.printf("數據綁定完成:【%s】%n", result) ;
    BindHandler.super.onFinish(name, target, context, result) ;
  }
}) ;
System.out.println(result) ;

輸出結果

圖片圖片

每個屬性在綁定時都會執行相應的回調方法。

3. 都用在哪里?

在SpringBoot環境中所有的數據綁定功能都是通過Binder進行。下面列出幾個非常重要的地方

3.1 SpringBoot啟動時綁定SpringApplication

SpringBoot在啟動時初始化環境配置Environment時,會將配置文件中的spring.main.*下的配置屬性綁定到當前的SpringApplication對象上。

public class SpringApplication {
  public ConfigurableApplicationContext run(String... args) {
    ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
  }
  private ConfigurableEnvironment prepareEnvironment(...) {
    // ...
    bindToSpringApplication(environment);    
  }  
  protected void bindToSpringApplication(ConfigurableEnvironment environment) {
    try {
      Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
    }
  }
}

spring.main有如下配置:

圖片圖片

3.2 綁定使用@ConfigurationProperties類

@ConfigurationProperties注解的類是通過BeanPostProcessor處理器執行綁定(不管是類上使用該注解,還是@Bean注解的方法都是通過該處理器進行綁定)。

public class ConfigurationPropertiesBindingPostProcessor {
  // 該類是由SpringBoot自動配置
  private ConfigurationPropertiesBinder binder;
  // 實例化bean,執行初始化方法之前
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 綁定;
    bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
    return bean;
  }
}

上面的ConfigurationPropertiesBean.get方法會處理當前bean實例是獨立的一個Bean對象且類上有@ConfigurationProperties注解,或者是當前的bean實例是通過@Bean定義且方法上有@ConfigurationProperties注解。不管是哪種定義的bean只要滿足條件,都會被包裝成ConfigurationPropertiesBean對象。接下來執行bind方法:

private void bind(ConfigurationPropertiesBean bean) {
  try {
    this.binder.bind(bean);
  }
}

執行綁定

class ConfigurationPropertiesBinder {
  BindResult<?> bind(ConfigurationPropertiesBean propertiesBean) {
    Bindable<?> target = propertiesBean.asBindTarget();
    ConfigurationProperties annotation = propertiesBean.getAnnotation();
    BindHandler bindHandler = getBindHandler(target, annotation);
    return getBinder().bind(annotation.prefix(), target, bindHandler);
  }
}

以上就是@ConfigurationProperties注解的類或方法對象通過Binder綁定的原理。

3.3 SpringCloud Gateway綁定路由謂詞&過濾器

當一個路由請求過來時,會查詢相應的路由,而這個查找過程中就會通過路由的定義信息轉換為Route對象。以下是大致過程(詳細還需要自行閱讀源碼)

public class RoutePredicateHandlerMapping {
  protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
    return lookupRoute(exchange)... ;
  }
  protected Mono<Route> lookupRoute(...) {
    // 查找路由
    return this.routeLocator.getRoutes()... ;
  }
}
public class RouteDefinitionRouteLocator {
  public Flux<Route> getRoutes() {
    // 將在yaml配置中定義的路由轉換為Route對象
    Flux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions().map(this::convertToRoute);
  }
  private Route convertToRoute(RouteDefinition routeDefinition) {
    AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
    // 獲取配置過濾器
    List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);
    return ... ;
  }
  private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
    List<GatewayFilter> filters = new ArrayList<>();
    if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
      // loadGatewayFilters方法中進行配置的綁定
      filters.addAll(loadGatewayFilters(routeDefinition.getId(),
          new ArrayList<>(this.gatewayProperties.getDefaultFilters())));
    }
  }
  List<GatewayFilter> loadGatewayFilters(...) {
    Object configuration = this.configurationService.with(factory)
      ...
      // 該方法執行綁定動作
      .bind();
  }
  public T bind() {
    T bound = doBind();
  }
  protected T doBind() {
    Bindable<T> bindable = Bindable.of(this.configurable.getConfigClass());
    T bound = bindOrCreate(bindable, this.normalizedProperties, this.configurable.shortcutFieldPrefix(),
        /* this.name, */this.service.validator.get(), this.service.conversionService.get());
    return bound;
  }
}

以上源碼比較粗略,大家只要知道原理即可,沒必要任何一個點都搞的清清楚楚。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2024-02-19 08:26:59

wxPython界面庫開發

2015-03-30 12:20:07

DemoStoryboard

2023-01-08 21:05:45

數據預警模型

2024-07-02 11:29:28

Typer庫Python命令

2020-09-29 15:08:47

Go UI框架開發

2014-05-23 10:37:37

聊天程序PHP聊天程序

2022-03-03 08:02:55

數據集成平臺

2020-11-15 18:20:44

GnuCash開源會計軟

2009-12-29 10:41:30

Ubuntu 9.10

2025-07-22 02:10:00

2025-01-08 06:00:00

Argus開源安全檢查工具

2025-01-07 13:00:00

日志分析平臺Graylog網絡安全

2024-04-30 08:20:54

代理工廠類Spring

2023-10-10 08:22:12

Tesseract庫開源

2023-12-16 13:22:00

JaVers控制框架

2021-03-06 07:00:00

awk文本分析工具Linux

2024-09-06 12:52:59

2013-04-23 14:32:28

創業創業者Mark Suster

2011-03-24 09:34:41

SPRING

2022-06-07 10:39:57

SpringBoot
點贊
收藏

51CTO技術棧公眾號

欧美日本不卡视频| 99久久久久久99| 外国成人激情视频| 欧美午夜美女看片| 在线观看欧美亚洲| 人妻视频一区二区三区| 好看的av在线不卡观看| 亚洲精品一二区| 成人av毛片在线观看| 免费在线小视频| 国产精品麻豆视频| 国模一区二区三区私拍视频| 国内av在线播放| 在线播放精品| 久久躁狠狠躁夜夜爽| 国产精品日韩欧美一区二区| 无码人妻丰满熟妇区96| 免费资源在线观看| 国产福利91精品| 国产精品久久久久久影视 | 99视频一区二区| 成人在线中文字幕| 国产一区二区视频网站| 亚洲三级影院| 久久成人精品视频| 国产精品国产三级国产专业不 | 欧美一级日本a级v片| 99re久久精品国产| 久久亚洲AV无码| 牛牛影视一区二区三区免费看| 欧美日本在线播放| 欧美日韩在线成人| 忘忧草在线影院两性视频| 亚洲欧美一区二区三区久本道91| 视频一区二区三| 天堂中文在线视频| www.亚洲色图.com| 国产免费一区二区| 性欧美8khd高清极品| 极品销魂美女一区二区三区| 日韩女在线观看| 夫妻免费无码v看片| 国产一区第一页| 清纯唯美亚洲经典中文字幕| 欧美精品一区二区三区四区| aaaaa黄色片| 欧美久久一区二区三区| 欧美亚洲丝袜传媒另类| 日韩一级在线免费观看| 在线中文字幕播放| 亚洲成人动漫av| 日本十八禁视频无遮挡| 波多野结衣精品| 亚洲午夜久久久久久久久电影院 | 国产精品九九九| 国产精品久久久久久久99| 欧美特黄色片| 欧美精品免费视频| 国产又黄又猛的视频| 国产91精品在线| 欧美日韩国产天堂| 91福利免费观看| 久久久国产精品入口麻豆| 欧美一区二区黄色| 2025中文字幕| 欧美一区二区三区红桃小说| 日韩激情片免费| 短视频在线观看| 欧美中文一区二区| 菠萝蜜一区二区| 亚洲精品成人久久| 中文字幕av网址| 久久网站免费观看| 伦理中文字幕亚洲| 国产精品9191| 免费精品视频| 欧美综合一区第一页| 毛片a片免费观看| 亚洲国产激情| 国产成人亚洲综合91| 正在播放亚洲精品| 国产精品综合在线视频| 国产精品日韩欧美一区二区三区| 日韩三级电影| 人妻一区二区三区免费| 久久中文娱乐网| 亚洲精品中文字幕乱码三区不卡| av免费在线观看网站| 午夜影院久久久| 十八禁视频网站在线观看| 91精品一久久香蕉国产线看观看| 欧美v国产在线一区二区三区| 99久久国产精| 婷婷六月综合| 91精品国产91久久久久久| 中文有码在线播放| 成人动漫一区二区在线| 日本午夜精品电影| 久无码久无码av无码| 麻豆视频网站在线观看| 五月天视频一区| 久久黄色片网站| 日本国产精品| 欧美成人激情在线| www.com亚洲| 高清在线观看日韩| 一本久道久久综合狠狠爱亚洲精品| 色呦呦在线播放| 欧美性xxxxxx少妇| 日本一级片在线播放| 国产精品成久久久久| 97香蕉超级碰碰久久免费的优势| 亚洲天堂中文字幕在线| 欧美韩日一区| 亚洲v日本v欧美v久久精品| av网站大全免费| 色8久久久久| 亚洲欧洲国产精品| 久久精品视频日本| 精品一区二区免费视频| 欧美午夜欧美| 3344国产永久在线观看视频| 在线不卡a资源高清| 中文字幕人妻一区二区| 99成人精品| 99久久精品免费看国产四区| 午夜激情视频在线| 在线观看中文字幕不卡| 国产精品久久不卡| 中文不卡1区2区3区| 97久久精品人人澡人人爽| 美女av免费观看| 日韩一区二区三区四区五区| 亚洲视频精品在线| av大片免费观看| 成人动漫视频在线| 精品人妻大屁股白浆无码| 国产精品亚洲综合在线观看| 日韩少妇与小伙激情| 一区二区视频在线免费观看| 欧美韩国日本一区| 国产自偷自偷免费一区 | 欧美v亚洲v| 日韩小视频在线观看专区| 欧美一级视频在线观看| 69视频免费看| 久久久精品中文字幕麻豆发布| 北条麻妃69av| 外国成人在线视频| 2019中文字幕在线| 神马精品久久| 欧美特级www| 国产又粗又猛又爽视频| 日韩av中文字幕一区二区三区| 欧美黑人3p| xxxxx.日韩| 日韩一级黄色av| 国产成人三级在线播放 | 亚洲免费在线观看av| a级高清视频欧美日韩| 亚洲视频免费看| 欧美在线观看成人| 国产乱码精品一区二区亚洲| 国产精品18久久久久久麻辣| 二区三区在线| 538prom精品视频线放| 青青青在线免费观看| 成人免费视频caoporn| 日本日本19xxxⅹhd乱影响| 亚洲国产精品嫩草影院久久av| 国产va免费精品高清在线观看| av中文资源在线| 这里只有精品视频在线观看| 国产小视频在线看| 久久婷婷国产综合国色天香 | 国产乱码精品一区二区三区五月婷 | 精品蜜桃一区二区三区| 成人免费看黄| 中文字幕av日韩| 国产黄色片网站| 天天色天天爱天天射综合| 人妻aⅴ无码一区二区三区| 久草中文综合在线| 日韩小视频网站| 精品久久不卡| 懂色一区二区三区av片| 国产精欧美一区二区三区蓝颜男同| 少妇高潮久久77777| 亚洲国产精彩视频| 日本精品视频一区二区| 青青草原在线免费观看| 91蝌蚪porny九色| 午夜欧美大片免费观看| 亚洲第一天堂网| 日本高清成人免费播放| 欧美成欧美va| 国产日韩欧美在线一区| 绯色av蜜臀vs少妇| 日日夜夜免费精品视频| 国产免费内射又粗又爽密桃视频| 西野翔中文久久精品国产| 国产有码一区二区| 综合另类专区| 欧美极品美女视频网站在线观看免费| 麻豆影视在线| 精品久久人人做人人爰| 伊人免费在线观看高清版| 亚洲成av人片观看| 亚洲综合图片一区| 久久综合九色综合97婷婷女人| 91在线视频成人| 中文字幕乱码人妻无码久久| 成人欧美一区二区三区视频网页 | 欧美成人xxxxx| 欧美日韩a区| 亚洲一区二区三区在线观看视频| 亚洲裸色大胆大尺寸艺术写真| 91gao视频| 91精品国产色综合久久不卡粉嫩| 日韩美女在线播放| free性m.freesex欧美| 伦伦影院午夜日韩欧美限制| 1024免费在线视频| 亚洲色图25p| 性猛交xxxx| 精品国产一区二区三区四区四| 性欧美丰满熟妇xxxx性仙踪林| 国产一区二区高清在线| 欧洲亚洲免费视频| 国产一线二线在线观看 | sm久久捆绑调教精品一区| 久久夜色撩人精品| 免费超碰在线| 中文字幕在线观看日韩| 国产黄色片在线播放| 亚洲精品视频免费| 欧美新色视频| 亚洲精品资源在线| 蜜桃视频在线观看www| 日韩免费高清av| 超碰人人人人人人| 日韩欧美色电影| 国产成人久久精品77777综合| 538prom精品视频线放| 国产精品国产三级国产aⅴ| 欧美影视资讯| 欧美日韩国产成人在线观看| 成人av黄色| 久久6免费高清热精品| 影音先锋在线播放| 欧美夫妻性生活视频| 日韩av毛片| 久久久欧美一区二区| bl在线肉h视频大尺度| 26uuu国产精品视频| 午夜激情在线播放| 国产mv免费观看入口亚洲| 日韩高清不卡| 国产在线视频欧美| 精品一区91| 国产日韩精品推荐| 亚洲动漫精品| 亚洲国产午夜伦理片大全在线观看网站 | 欧美爱爱视频网站| 伊人青青综合网| 久久精品xxx| 国产欧美不卡| www.com操| 国产一区二区三区久久久| 涩视频在线观看| 91女人视频在线观看| 东方伊人免费在线观看| 中文字幕一区二区三区蜜月| 久草视频手机在线观看| 精品国产鲁一鲁一区二区张丽| 精品久久久久久久久久久久久久久久| 欧美日韩一区二区电影| www.亚洲天堂.com| 中文字幕一区二区三区欧美日韩 | 久久久久国产精品区片区无码| 久久久三级国产网站| 婷婷国产成人精品视频| 亚洲综合成人在线| 神马久久久久久久 | 欧美捆绑视频| 色偷偷9999www| 高清毛片在线观看| 国产精品自在线| 黑色丝袜福利片av久久| 色一情一区二区三区四区| 欧美激情aⅴ一区二区三区| 不要播放器的av网站| 国产一区二区电影| 久久精品国产亚洲av久| 欧美成人精品一区二区男人小说| 国语对白做受69| 国产美女久久| 国产精品一区二区欧美| 欧美在线电影| heyzo亚洲| 国产一区二区精品久久| av手机在线播放| 亚洲国产日日夜夜| 亚洲天天综合网| 亚洲男人天堂2019| 免费毛片在线看片免费丝瓜视频 | 久久久精品一品道一区| 久久久久久国产精品视频| 欧美日韩中文字幕一区二区| 午夜视频免费看| 欧美日韩成人在线观看| 国产精成人品2018| 国产午夜精品理论片a级探花| 欧美自拍偷拍网| 亚洲精品精品亚洲| 亚洲视频在线免费播放| 国产视频一区在线| 超碰在线中文字幕| 亚洲在线第一页| 97视频热人人精品免费| 欧美一级黄色影院| 91日韩精品一区| 亚洲一区二区91| 日韩一级完整毛片| 麻豆电影在线播放| 国产精品久久97| 久久99久久人婷婷精品综合| 成人中文字幕在线播放| 成人激情小说网站| 久久久久久久久久久网| 日韩一区二区视频在线观看| 日本在线www| 国产剧情日韩欧美| 欧美色图国产精品| 国产高清精品一区二区| 欧美日韩影视| 九九久久精品一区| 国产一区二区久久久久| 精品一区二区成人免费视频 | 18成人免费观看网站下载| 久久福利综合| 一区二区xxx| 国产精品乱码一区二三区小蝌蚪| 无码人妻av免费一区二区三区 | 国产在线精品免费av| 日韩av片在线免费观看| 欧美三级乱人伦电影| 成人综合影院| 亚洲伊人伊色伊影伊综合网| 伊人中文字幕在线观看| 亚洲欧美在线第一页| 台湾佬成人网| 欧美一二三四五区| 久久亚洲精品伦理| 青娱乐国产视频| 欧美日韩国产综合草草| 老司机在线视频二区| 成人两性免费视频| 91成人影院| 国产香蕉精品视频| 午夜欧美视频在线观看| 深夜福利视频在线免费观看| 日韩免费不卡av| 99精品电影| 欧美日韩一区二区区| 亚洲成人午夜影院| 日本午夜在线视频| 国产精品色视频| 一区二区三区国产精华| 91精品又粗又猛又爽| 一本色道久久综合亚洲aⅴ蜜桃| 男人天堂综合| 欧美亚洲国产一区在线观看网站 | 成人午夜电影在线观看| 91亚洲国产成人精品性色| 国内精品久久久久久久影视蜜臀| www.17c.com喷水少妇| 色美美综合视频| 日韩美女网站| 国产一区二区三区免费不卡| 久久亚洲精选| 免费在线观看黄视频| 日韩成人在线视频| 久久久精品一区二区毛片免费看| 日本丰满大乳奶| 久久亚洲捆绑美女| 国产女无套免费视频| 欧美最猛性xxxxx免费| 小处雏高清一区二区三区| 亚洲日本久久久| 欧美无人高清视频在线观看| 污污的视频在线观看| 蜜桃麻豆91| 国产精品影视在线观看| 天堂网中文字幕| 国产成人av电影在线观看| 少妇高潮一69aⅹ| 91国产成人在线| 国产美女情趣调教h一区二区| 午夜久久资源|