精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产色无码精品视频国产| 国产精品电影院| 精品久久久久久中文字幕| 国产亚洲精品一区二555| 男女激烈动态图| 日本精品入口免费视频| 久久精品国产亚洲blacked| 国产精品福利av| 99视频免费观看| 欧洲美女女同性互添| 网友自拍亚洲| 91伊人久久大香线蕉| 欧美福利小视频| 精品人妻一区二区三| 美女隐私在线观看| 欧美裸体在线版观看完整版| 午夜精品久久久久久久蜜桃app| 亚洲最大成人免费视频| 三级在线观看免费大全| av综合网址| 亚洲最新视频在线播放| 91久久精品国产91久久性色tv| 日韩精品久久久久久久的张开腿让| 欧美18—19sex性hd| 成人欧美一区二区三区白人| 国产综合色香蕉精品| 青娱乐国产视频| 99久久精品一区二区成人| 欧美国产一区视频在线观看| 国产精品久久9| 激情无码人妻又粗又大| 日韩精品社区| 91久久精品一区二区三| 日本精品一区二区三区视频 | 国产精品乱码久久久久久| 日本欧美一二三区| 国产精品1000部啪视频| 在线成人av观看| 久久精品亚洲精品国产欧美 | 99久久99久久精品免费观看 | 97人洗澡人人免费公开视频碰碰碰| 性生交大片免费看l| 欧美xxx黑人xxx水蜜桃| 高清免费成人av| 97香蕉久久夜色精品国产| 来吧亚洲综合网| 欧美日韩国产传媒| 日韩高清中文字幕| 99视频在线免费| 里番在线观看网站| 久久国产免费看| 欧美xxxx做受欧美| 欧美xxxxx少妇| 欧洲亚洲两性| 日韩欧美中文在线| 亚洲一区二区在线看| 性少妇videosexfreexxx片| 亚洲成人三区| 亚洲精品av在线播放| 黄色片视频在线播放| 日本免费在线观看| 成人黄页毛片网站| 国产精品久久久久久亚洲影视 | 五月婷婷丁香六月| 日本美女一区二区| 欧美裸体xxxx极品少妇| 日韩精品卡通动漫网站| 亚洲人和日本人hd| 日韩美女在线视频| 亚洲色精品三区二区一区| 国偷自产一区二区免费视频| 色哟哟欧美精品| 日韩欧美猛交xxxxx无码| 国产youjizz在线| 成人午夜电影网站| 成人黄色片网站| 中日韩黄色大片| 综合激情视频| 在线观看精品国产视频| 日韩av无码一区二区三区不卡| jizz亚洲女人高潮大叫| 91精品国产全国免费观看| 精品免费国产一区二区| 欧美激情不卡| 色婷婷国产精品综合在线观看| 免费看污黄网站| 日本不卡1234视频| 亚洲免费观看高清完整| 色一情一乱一伦一区二区三欧美 | 久久久99精品视频| 精品三级久久久久久久电影聊斋| 粉嫩一区二区三区在线看| 国产区二精品视| 国产av无码专区亚洲a∨毛片| 天堂va蜜桃一区二区三区 | 成人黄色在线网站| 欧美日韩亚洲一区二区三区四区| 成 人 黄 色 片 在线播放| av成人免费在线| 国产91精品一区二区绿帽| 国产又粗又黄又爽的视频| 久久精品中文| 欧美中文字幕在线播放| 日韩大片免费在线观看| 国自产拍偷拍福利精品免费一| 久久夜色精品国产| 亚洲精品久久久久久国| 亚洲高清激情| 久久人91精品久久久久久不卡| 久草免费在线视频观看| 国产一区亚洲| 国产精品久久久久aaaa九色| 亚洲精品久久久久久久久久久久久久 | 韩国av永久免费| 国产一区二区三区在线观看精品| 国产精品入口福利| 蜜桃av噜噜一区二区三区麻豆| 久久精品国产77777蜜臀| 福利精品视频| 免费av不卡| 欧洲在线/亚洲| 亚洲一级免费观看| 成人久久网站| 亚洲精品成人久久电影| 国产精品 欧美激情| 一本精品一区二区三区| 奇门遁甲1982国语版免费观看高清 | 久久资源在线| 国产精品日韩一区二区三区| 亚洲免费成人在线| 国产精品国产三级国产有无不卡| 欧美韩国日本在线| 秋霞国产精品| 欧美一三区三区四区免费在线看| 亚洲精品一区二区三区影院忠贞| 99精品视频网| 国产精品女视频| 亚洲人视频在线观看| 亚洲图片一区二区| 999在线观看视频| 日韩国产网站| 欧美一区二区国产| 亚洲人做受高潮| 蜜桃精品视频在线观看| 91青青草免费观看| 求av网址在线观看| 欧美日韩一级片在线观看| 成人三级做爰av| 一区三区在线欧| 91精品国产91久久久久| 在线视频1卡二卡三卡| 国产成人精品免费网站| www亚洲国产| 国产777精品精品热热热一区二区| 在线精品观看国产| 国产中年熟女高潮大集合| 亚洲精品电影| 亚洲一区二区中文| 日本动漫同人动漫在线观看| 日韩欧美的一区| 国产真实夫妇交换视频| 日本va欧美va欧美va精品| 午夜精品视频在线观看一区二区| 朝桐光一区二区| 最新91在线视频| 四虎永久在线精品| av成人免费在线| 亚洲成熟丰满熟妇高潮xxxxx| 九九亚洲视频| 欧美激情一区二区三区在线视频观看 | 国产精品久久久久av| 一级毛片视频在线| 欧美精品在线视频| 亚洲熟妇一区二区三区| 丝袜美腿亚洲综合| 亚洲韩国在线| 亚洲天堂av在线| 欧美成人精品福利| 国产黄a三级三级| 国产精品一区二区在线观看不卡| 日韩久久在线| 亚洲天堂av在线| 在线观看欧美成人| 国产精品毛片一区视频播 | 蜜桃av一区二区| 老司机午夜网站| 成人精品动漫| 久久成年人视频| 亚洲av毛片成人精品| 欧美日韩一区在线| 久久久久久久黄色| 黄色日韩网站视频| 日韩欧美一区二区三区四区 | 欧美日韩另类综合| 爱情电影网av一区二区| 国产亚洲欧洲黄色| 国产普通话bbwbbwbbw| 国产精品久久影院| av天堂一区二区| 欧美午夜一区| 999久久久| 日韩电影免费观看高清完整版| 日韩在线视频观看| 日本黄色免费视频| 欧美猛男超大videosgay| 国产无遮挡又黄又爽在线观看| 国产日韩欧美制服另类| 不卡av免费在线| 国产精品va| 午夜老司机精品| 麻豆国产欧美一区二区三区r| 国产精品一区二区三区毛片淫片| 在线观看av黄网站永久| 亚洲国产精彩中文乱码av| 国产无遮挡aaa片爽爽| 国产精品美女久久久久久久| 天天躁日日躁狠狠躁av麻豆男男| 久久 天天综合| 国产手机视频在线观看| 九九综合九九| 国产日韩在线一区二区三区| 日韩欧国产精品一区综合无码| 日韩亚洲欧美成人| 国产人妖在线播放| 欧洲国内综合视频| 在线观看精品国产| 久久久久久久久久久久久夜| wwwxxxx在线观看| 久久www免费人成看片高清| 欧美精品无码一区二区三区| 亚洲神马久久| 日韩精品资源| 妖精视频一区二区三区免费观看| 国产免费一区二区| 久久国际精品| 97精品一区二区视频在线观看| av在线免费观看网址| 精品国产凹凸成av人导航| 天天综合网入口| 亚洲一区成人在线| 99久久婷婷国产综合| 中文字幕一区二区三中文字幕| 香蕉视频久久久| 久久精品在这里| 精品人妻一区二区三区蜜桃视频| 久久伊人蜜桃av一区二区| 国产精品久久a| 秋霞午夜av一区二区三区| 日韩网址在线观看| 亚洲欧美日本视频在线观看| 一本久道久久综合狠狠爱亚洲精品| 中文有码一区| 欧美色欧美亚洲另类七区| 香蕉视频一区| 欧美精品欧美精品| 蜜桃视频欧美| 日韩精品第一页| 久久国产精品亚洲人一区二区三区| 99久久精品免费看国产一区二区三区 | 在线国产一区| 粉嫩av一区二区三区天美传媒| 欧美午夜视频| 日韩中文字幕在线视频观看| 欧美gay男男猛男无套| 国产精品区一区二区三含羞草| jizz18欧美18| 精品乱码一区二区三区| 亚洲aⅴ网站| 91中文精品字幕在线视频| 国产一区二区三区| 国产精品精品视频| 欧美成人高清视频在线观看| 成人xxxxx| 风间由美性色一区二区三区四区| 91久久精品一区| 校园春色亚洲色图| 国产美女主播一区| 日韩精品视频中文字幕| 国产欧美在线播放| 99精品视频在线免费播放| 99国产在线观看| 欧美美女黄色| 国产精品三区四区| 亚洲警察之高压线| 在线免费观看一区二区三区| 国产成人黄色| 免费精品视频一区| 成人av动漫| 欧美一区二区三区精美影视| 99久久九九| 亚洲人体一区| 精品白丝av| 黄色成人免费看| 国产不卡一区视频| 在线不卡av电影| 91麻豆产精品久久久久久 | 日韩在线观看一区二区三区| 久久国产精品久久| 波多野结衣在线一区二区 | 亚洲成人av免费在线观看| 国产精品1区二区.| 一区二区三区国产好的精华液| 裸体一区二区三区| 日本一级大毛片a一| 国产亚洲欧洲一区高清在线观看| 欧美偷拍第一页| 在线日韩国产精品| 欧美性猛交 xxxx| 日韩在线播放视频| 成人片免费看| 国产精品久久久久免费| 欧美韩日高清| 日韩精品一区二区三区不卡| 不卡视频在线观看| 麻豆精品一区二区三区视频| 亚洲女女做受ⅹxx高潮| 五月天激情四射| 日本精品视频一区二区三区| 亚洲第一免费视频| 色噜噜狠狠色综合网图区| 中文字幕在线视频网站| 91久久精品国产91久久性色tv | 国产无套内射久久久国产| 国产成人综合网站| 99热在线观看精品| 欧美日韩综合色| 男人天堂亚洲二区| 一区二区在线视频播放| 不卡专区在线| 成人av免费电影| 亚洲视频在线免费| 亚洲成人天堂网| 国产不卡高清在线观看视频| 午夜黄色福利视频| 亚洲精选视频在线| 国产又粗又猛又色又| 中文字幕精品在线视频| 精品176二区| 国产一区二区丝袜| 日韩国产一区二区| 91人人澡人人爽人人精品| 久久噜噜亚洲综合| 久久99国产综合精品免费| 欧美在线观看视频在线| 99精品在线看| 久久伊人精品一区二区三区| 豆花视频一区| 影音先锋成人资源网站| 国产乱国产乱300精品| 欧美日韩中文字幕在线观看| 日韩欧美成人激情| 欧美xxxx性xxxxx高清| 国产精成人品localhost| 亚洲第一伊人| 少妇精品一区二区三区| 亚洲成人激情综合网| 中文字幕av免费观看| 日韩美女一区二区三区| 青草影视电视剧免费播放在线观看| 91久久精品国产91久久性色tv| 欧美午夜不卡影院在线观看完整版免费| 日韩精品――色哟哟| 午夜亚洲福利老司机| 日本在线丨区| 欧美激情久久久| 精品av导航| 日韩亚洲在线视频| 中文字幕成人在线观看| www..com国产| 亚洲欧美日韩成人| 国产网红女主播精品视频| 国产欧美一区二区三区久久人妖| 羞羞色午夜精品一区二区三区| 69久久精品无码一区二区| 亚洲成人精品一区| 国外av在线| 亚洲综合在线播放| 亚洲精品人人| 久久久久国产免费| 欧美日韩精品在线| 亚洲精品18p| 欧美一区二区大胆人体摄影专业网站| 麻豆国产一区二区三区四区| 无码 制服 丝袜 国产 另类| 国产精品一区在线观看你懂的| 国产一级片免费| 亚洲偷熟乱区亚洲香蕉av| **精品中文字幕一区二区三区| 久久人人爽人人爽人人av| 久久久久久久综合色一本| 国产乱人乱偷精品视频a人人澡| 国内精品久久久久影院优| 成人久久久久| 久久综合久久色| 亚洲精品视频观看| 色在线免费视频| 91精品啪aⅴ在线观看国产| 国产精品日本欧美一区二区三区| 可以免费看av的网址| 日韩电视剧免费观看网站|