日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

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

來源: 責編: 時間:2024-05-09 09:25:56 251觀看
導讀環境:SpringBoot3.2.51. 簡介本篇文章將介紹Spring Boot中一個非常強大且十分重要的類Binder,該類可以將外部配置文件的屬性值綁定到Spring Boot應用程序中的Java對象上。在Spring Boot中,通常使用@ConfigurationPropert

環境:SpringBoot3.2.572X28資訊網——每日最新資訊28at.com

1. 簡介

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

2. 實戰案例

2.1 準備綁定對象

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

配置文件中添加配置屬性72X28資訊網——每日最新資訊28at.com

pack:  person:   age: 20   name: 張三

測試綁定組件72X28資訊網——每日最新資訊28at.com

@Componentpublic 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 {    // 綁定測試都將在這里完成  }}

后續案例都將基于上面的環境72X28資訊網——每日最新資訊28at.com

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兩個類型轉換器。72X28資訊網——每日最新資訊28at.com

2.3 自定義數據類型轉換

給Person添加Date類型的字段,如下:72X28資訊網——每日最新資訊28at.com

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

在此執行上面2.2中代碼,程序拋出了如下異常72X28資訊網——每日最新資訊28at.com

圖片圖片72X28資訊網——每日最新資訊28at.com

默認的數據類型轉換器是沒有String到Date轉換功能。我們需要添加自定義的類型轉換,如下自定義類型轉換器:72X28資訊網——每日最新資訊28at.com

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

修改數據綁定方式72X28資訊網——每日最新資訊28at.com

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

這次成功輸出結果。72X28資訊網——每日最新資訊28at.com

圖片72X28資訊網——每日最新資訊28at.com

2.4 數據綁定回調

我們還可以為Binder執行綁定時,傳入回調句柄,這樣在數據綁定的各個階段都可以進行相應的處理,如下示例:72X28資訊網——每日最新資訊28at.com

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

輸出結果72X28資訊網——每日最新資訊28at.com

圖片圖片72X28資訊網——每日最新資訊28at.com

每個屬性在綁定時都會執行相應的回調方法。72X28資訊網——每日最新資訊28at.com

3. 都用在哪里?

在SpringBoot環境中所有的數據綁定功能都是通過Binder進行。下面列出幾個非常重要的地方72X28資訊網——每日最新資訊28at.com

3.1 SpringBoot啟動時綁定SpringApplication

SpringBoot在啟動時初始化環境配置Environment時,會將配置文件中的spring.main.*下的配置屬性綁定到當前的SpringApplication對象上。72X28資訊網——每日最新資訊28at.com

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有如下配置:72X28資訊網——每日最新資訊28at.com

圖片圖片72X28資訊網——每日最新資訊28at.com

3.2 綁定使用@ConfigurationProperties類

@ConfigurationProperties注解的類是通過BeanPostProcessor處理器執行綁定(不管是類上使用該注解,還是@Bean注解的方法都是通過該處理器進行綁定)。72X28資訊網——每日最新資訊28at.com

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方法:72X28資訊網——每日最新資訊28at.com

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

執行綁定72X28資訊網——每日最新資訊28at.com

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綁定的原理。72X28資訊網——每日最新資訊28at.com

3.3 SpringCloud Gateway綁定路由謂詞&過濾器72X28資訊網——每日最新資訊28at.com

當一個路由請求過來時,會查詢相應的路由,而這個查找過程中就會通過路由的定義信息轉換為Route對象。以下是大致過程(詳細還需要自行閱讀源碼)72X28資訊網——每日最新資訊28at.com

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;  }}

以上源碼比較粗略,大家只要知道原理即可,沒必要任何一個點都搞的清清楚楚。72X28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-87490-0.htmlSpringBoot一個非常強大的數據綁定類

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 使用Ollama和Go基于文本嵌入模型實現文本向量化

下一篇: RabbitMQ如何保證消息可靠性?

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美电影在线播放| 欧美一区二区三区久久精品| 国产香蕉97碰碰久久人人| 欧美日韩亚洲一区在线观看| 欧美精品一区二区三| 蘑菇福利视频一区播放| 牛夜精品久久久久久久99黑人| 美女日韩欧美| 欧美激情第一页xxx| 欧美色网在线| 亚洲作爱视频| 亚洲一区久久久| 久久久免费精品| 欧美精品一区二区蜜臀亚洲| 国产精品自拍网站| 亚洲高清色综合| 一本久道久久综合中文字幕| 久久国内精品自在自线400部| 欧美岛国激情| 国产欧美日韩一区| 亚洲人精品午夜| 午夜伦理片一区| 麻豆久久婷婷| 国产精品久久久久久超碰| 加勒比av一区二区| 99视频一区二区三区| 欧美在现视频| 欧美精选一区| 国产在线不卡精品| 99在线热播精品免费99热| 久久精品国产在热久久| 欧美日韩精品| 怡红院精品视频在线观看极品| 亚洲特级片在线| 另类酷文…触手系列精品集v1小说| 国产精品v欧美精品v日韩| 亚洲成在人线av| 欧美一级视频精品观看| 欧美激情中文字幕一区二区 | 欧美日韩黄色一区二区| 国产一区在线观看视频| 国产一区二区三区av电影| 99re66热这里只有精品4| 久久久青草婷婷精品综合日韩| 欧美私人网站| 亚洲国产日韩一区| 性久久久久久| 国产精品va在线播放我和闺蜜| …久久精品99久久香蕉国产| 午夜久久久久| 国产精品久久久久久久午夜片| 亚洲精品国产精品乱码不99| 久久天天躁夜夜躁狠狠躁2022| 国产精品自拍网站| 亚洲亚洲精品三区日韩精品在线视频 | 亚洲一区二区三区久久| 欧美精选一区| 91久久久久久久久久久久久| 久久久久这里只有精品| 国产日韩欧美黄色| 亚洲欧美乱综合| 欧美调教vk| av成人天堂| 欧美精品国产| 亚洲精品国产系列| 欧美二区在线播放| 在线不卡视频| 久久人人爽人人爽爽久久| 国产亚洲成av人在线观看导航| 亚洲免费综合| 国产精品影音先锋| 亚洲欧美在线高清| 国产欧美日韩精品一区| 性亚洲最疯狂xxxx高清| 国产精品亚洲片夜色在线| 亚洲永久免费精品| 国产精品久久久一区二区三区| 亚洲性视频网址| 国产精品视频内| 性欧美大战久久久久久久久| 国产精品亚洲а∨天堂免在线| 亚洲欧美另类国产| 国产美女诱惑一区二区| 欧美一区二区三区日韩| 国产欧美一区二区色老头| 久久av一区二区三区漫画| 国产日韩精品在线| 久久久91精品国产一区二区三区| 国产一区自拍视频| 玖玖综合伊人| 91久久线看在观草草青青| 欧美激情一二区| 亚洲乱码国产乱码精品精| 欧美乱大交xxxxx| 日韩午夜av电影| 欧美午夜视频| 亚欧成人精品| 黑丝一区二区三区| 免费黄网站欧美| 亚洲久久一区| 欧美三级视频| 午夜激情亚洲| 一色屋精品亚洲香蕉网站| 欧美.www| 日韩网站在线| 国产欧美日韩精品a在线观看| 久久久久久综合| 亚洲国产乱码最新视频| 欧美日韩国产电影| 亚洲欧美变态国产另类| 国产一二精品视频| 蜜桃久久av一区| 一区二区国产精品| 国产拍揄自揄精品视频麻豆| 久久久之久亚州精品露出| 亚洲精品系列| 国产欧美日韩精品专区| 噜噜噜久久亚洲精品国产品小说| 亚洲乱码国产乱码精品精| 国产精品国产福利国产秒拍| 久久国产精品99国产精| 91久久精品日日躁夜夜躁欧美 | 欧美日韩国产在线播放网站| 亚洲永久视频| 韩国在线视频一区| 欧美极品色图| 欧美在线地址| 亚洲精品国产精品乱码不99按摩| 国产精品ⅴa在线观看h| 久久久久看片| 一区二区三区视频观看| 很黄很黄激情成人| 欧美日韩另类在线| 久久精品青青大伊人av| 日韩一区二区精品葵司在线| 国产欧美一区二区色老头 | 欧美深夜影院| 鲁大师影院一区二区三区| 这里只有视频精品| 国模私拍一区二区三区| 欧美日本视频在线| 久久精品久久综合| 一区二区三区四区蜜桃| 一色屋精品视频在线看| 国产精品免费观看在线| 欧美电影在线| 欧美一区二区国产| 99re6热只有精品免费观看| 国产毛片久久| 欧美日韩国产精品成人| 久久久久久夜| 亚洲欧美日韩精品久久| 亚洲精品黄色| 狠久久av成人天堂| 国产精品久久久久久久久久ktv | 午夜亚洲激情| 夜夜嗨av一区二区三区网站四季av | 欧美精品一区视频| 久久精品国产亚洲一区二区三区| 中文国产亚洲喷潮| 亚洲电影免费观看高清完整版在线观看 | 午夜日韩av| 99在线精品免费视频九九视| 影院欧美亚洲| 国产情侣久久| 国产精品久久久久久影院8一贰佰| 免播放器亚洲一区| 久久久久se| 午夜精品久久久久久久白皮肤| 日韩午夜精品视频| 亚洲国产成人porn| 韩国av一区二区| 国产视频亚洲精品| 国产精品久久毛片a| 欧美日韩亚洲天堂| 欧美极品在线视频| 你懂的视频一区二区| 久久综合久久综合这里只有精品| 性做久久久久久免费观看欧美| 亚洲午夜一区二区三区| 9人人澡人人爽人人精品| 亚洲激情网站| 在线看国产日韩| 黑人极品videos精品欧美裸| 国产欧美一区二区精品忘忧草| 国产精品毛片在线| 国产精品久久| 欧美视频中文字幕在线| 欧美日韩另类视频| 欧美区日韩区| 欧美日韩国产在线播放网站| 欧美激情亚洲自拍| 欧美精品久久99久久在免费线| 美女精品网站| 另类av一区二区| 免费亚洲一区二区| 欧美成人影音| 欧美国产日韩a欧美在线观看| 欧美成人高清| 欧美巨乳在线观看| 欧美三级电影一区| 欧美香蕉视频| 国产精品免费在线| 国产精品一区在线观看你懂的 |