AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

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

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

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

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

1. 簡介

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

2. 實戰案例

2.1 準備綁定對象

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

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

pack:  person:   age: 20   name: 張三

測試綁定組件sYx28資訊網——每日最新資訊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 {    // 綁定測試都將在這里完成  }}

后續案例都將基于上面的環境sYx28資訊網——每日最新資訊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兩個類型轉換器。sYx28資訊網——每日最新資訊28at.com

2.3 自定義數據類型轉換

給Person添加Date類型的字段,如下:sYx28資訊網——每日最新資訊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中代碼,程序拋出了如下異常sYx28資訊網——每日最新資訊28at.com

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

默認的數據類型轉換器是沒有String到Date轉換功能。我們需要添加自定義的類型轉換,如下自定義類型轉換器:sYx28資訊網——每日最新資訊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) ;        }      }    });  }}

修改數據綁定方式sYx28資訊網——每日最新資訊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) ;

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

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

2.4 數據綁定回調

我們還可以為Binder執行綁定時,傳入回調句柄,這樣在數據綁定的各個階段都可以進行相應的處理,如下示例:sYx28資訊網——每日最新資訊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) ;

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

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

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

3. 都用在哪里?

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

3.1 SpringBoot啟動時綁定SpringApplication

SpringBoot在啟動時初始化環境配置Environment時,會將配置文件中的spring.main.*下的配置屬性綁定到當前的SpringApplication對象上。sYx28資訊網——每日最新資訊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有如下配置:sYx28資訊網——每日最新資訊28at.com

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

3.2 綁定使用@ConfigurationProperties類

@ConfigurationProperties注解的類是通過BeanPostProcessor處理器執行綁定(不管是類上使用該注解,還是@Bean注解的方法都是通過該處理器進行綁定)。sYx28資訊網——每日最新資訊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方法:sYx28資訊網——每日最新資訊28at.com

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

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

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

當一個路由請求過來時,會查詢相應的路由,而這個查找過程中就會通過路由的定義信息轉換為Route對象。以下是大致過程(詳細還需要自行閱讀源碼)sYx28資訊網——每日最新資訊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;  }}

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

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

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

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

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

標簽:
  • 熱門焦點
Top