最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot外部化配置實(shí)戰(zhàn)解析

 更新時(shí)間:2019年06月04日 10:24:12   作者:宜信技術(shù)  
這篇文章主要介紹了Spring Boot外部化配置實(shí)戰(zhàn)解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、流程分析

1.1 入口程序

在 SpringApplication#run(String... args) 方法中,外部化配置關(guān)鍵流程分為以下四步

public ConfigurableApplicationContext 

run(String... args) {

  ...

  SpringApplicationRunListeners listeners = getRunListeners(args); // 1

  listeners.starting();

  try {

    ApplicationArguments applicationArguments = new DefaultApplicationArguments(

      args);

    ConfigurableEnvironment environment = prepareEnvironment(listeners,

                                 applicationArguments); // 2

    configureIgnoreBeanInfo(environment);

    Banner printedBanner = printBanner(environment);

    context = createApplicationContext();

    exceptionReporters = getSpringFactoriesInstances(

      SpringBootExceptionReporter.class,

      new Class[] { ConfigurableApplicationContext.class }, context);

    prepareContext(context, environment, listeners, applicationArguments,

            printedBanner); // 3

    refreshContext(context); // 4

    afterRefresh(context, applicationArguments);

    stopWatch.stop();

    if (this.logStartupInfo) {

      new StartupInfoLogger(this.mainApplicationClass)

        .logStarted(getApplicationLog(), stopWatch);

    }

    listeners.started(context);

    callRunners(context, applicationArguments);

  }

  ...

}

1.2 關(guān)鍵流程思維導(dǎo)圖

1.3 關(guān)鍵流程詳解

對(duì)入口程序中標(biāo)記的四步,分析如下

1.3.1 SpringApplication#getRunListeners

加載 META-INF/spring.factories

獲取 SpringApplicationRunListener

的實(shí)例集合,存放的對(duì)象是 EventPublishingRunListener 類型 以及自定義的 SpringApplicationRunListener 實(shí)現(xiàn)類型

1.3.2 SpringApplication#prepareEnvironment

prepareEnvironment 方法中,主要的三步如下

private ConfigurableEnvironment 

prepareEnvironment(SpringApplicationRunListeners listeners,

  ApplicationArguments applicationArguments) {

  // Create and configure the environment

  ConfigurableEnvironment environment = getOrCreateEnvironment(); // 2.1

  configureEnvironment(environment, applicationArguments.getSourceArgs()); // 2.2

  listeners.environmentPrepared(environment); // 2.3

  ...

  return environment;

}

1) getOrCreateEnvironment 方法

在 WebApplicationType.SERVLET web應(yīng)用類型下,會(huì)創(chuàng)建 StandardServletEnvironment,本文以 StandardServletEnvironment 為例,類的層次結(jié)構(gòu)如下

當(dāng)創(chuàng)建 StandardServletEnvironment,StandardServletEnvironment 父類 AbstractEnvironment 調(diào)用 customizePropertySources 方法,會(huì)執(zhí)行 StandardServletEnvironment#customizePropertySources和 StandardEnvironment#customizePropertySources ,源碼如下AbstractEnvironment

public AbstractEnvironment() {

  customizePropertySources(this.propertySources);

  if (logger.isDebugEnabled()) {

    logger.debug("Initialized " + getClass().getSimpleName() + " with PropertySources " + this.propertySources);

  }

}

StandardServletEnvironment#customizePropertySources

/** Servlet context init parameters property source name: {@value} */

public static final 

StringSERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";

/** Servlet config init parameters property source name: {@value} */

public static final String 

SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";

/** JNDI property source name: {@value} */

public static final String 

JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";

@Override

protected void customizePropertySources(MutablePropertySources propertySources) {

  propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));

  propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));

  if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {

    propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));

  }

  super.customizePropertySources(propertySources);

}

StandardEnvironment#customizePropertySources

/** System environment property source name: {@value} */

public static final String 

SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";

/** JVM system properties property source name: {@value} */

public static final String 

SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

@Override

protected void customizePropertySources(MutablePropertySources propertySources) {

  propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));

  propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,getSystemEnvironment());

}

PropertySources 順序:

  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment

PropertySources 與 PropertySource 關(guān)系為 1 對(duì) N

2) configureEnvironment 方法

調(diào)用 configurePropertySources(environment, args), 在方法里面設(shè)置 Environment 的 PropertySources , 包含 defaultProperties 和

SimpleCommandLinePropertySource(commandLineArgs),PropertySources 添加 defaultProperties 到最后,添加

SimpleCommandLinePropertySource(commandLineArgs)到最前面

PropertySources 順序:

  • commandLineArgs
  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment
  • defaultProperties

3) listeners.environmentPrepared 方法

會(huì)按優(yōu)先級(jí)順序遍歷執(zhí)行 SpringApplicationRunListener#environmentPrepared,比如 EventPublishingRunListener 和 自定義的 SpringApplicationRunListener

EventPublishingRunListener 發(fā)布

ApplicationEnvironmentPreparedEvent 事件

ConfigFileApplicationListener 監(jiān)聽

ApplicationEvent 事件 、處理 ApplicationEnvironmentPreparedEvent 事件,加載所有 EnvironmentPostProcessor 包括自己,然后按照順序進(jìn)行方法回調(diào)

---ConfigFileApplicationListener#postProcessEnvironment方法回調(diào) ,然后addPropertySources 方法調(diào)用

RandomValuePropertySource#addToEnvironment,在 systemEnvironment 后面添加 random,然后添加配置文件的屬性源(詳見源碼ConfigFileApplicationListener.Loader#load()

擴(kuò)展點(diǎn)

  • 自定義 SpringApplicationRunListener ,重寫 environmentPrepared 方法
  • 自定義 EnvironmentPostProcessor
  • 自定義 ApplicationListener 監(jiān)聽 ApplicationEnvironmentPreparedEvent 事件
  • ConfigFileApplicationListener,即是 EnvironmentPostProcessor ,又是 ApplicationListener ,類的層次結(jié)構(gòu)如下

@Override

public void onApplicationEvent(ApplicationEvent event) {

  // 處理 ApplicationEnvironmentPreparedEvent 事件

  if (event instanceof ApplicationEnvironmentPreparedEvent) {

    onApplicationEnvironmentPreparedEvent(

      (ApplicationEnvironmentPreparedEvent) event);

  }

  // 處理 ApplicationPreparedEvent 事件

  if (event instanceof ApplicationPreparedEvent) {

    onApplicationPreparedEvent(event);

  }

}

private void onApplicationEnvironmentPreparedEvent(

  ApplicationEnvironmentPreparedEvent event) {

  // 加載 META-INF/spring.factories 中配置的 EnvironmentPostProcessor

  List

  // 加載自己 ConfigFileApplicationListener

  postProcessors.add(this);

  // 按照 Ordered 進(jìn)行優(yōu)先級(jí)排序

  AnnotationAwareOrderComparator.sort(postProcessors);

  // 回調(diào) EnvironmentPostProcessor

  for (EnvironmentPostProcessor postProcessor : postProcessors) {

    postProcessor.postProcessEnvironment(event.getEnvironment(),                      event.getSpringApplication());

  }

}

List

  return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class,                        getClass().getClassLoader());

}

@Override

public void 

postProcessEnvironment(ConfigurableEnvironment environment,

                  SpringApplication application) {

  addPropertySources(environment, application.getResourceLoader());

}

/**

 * Add config file property sources to the specified environment.

 * @param environment the environment to add source to

 * @param resourceLoader the resource loader

 * @see 

#addPostProcessors(ConfigurableApplicationContext)

 */

protected void 

addPropertySources(ConfigurableEnvironment environment,

                 ResourceLoader resourceLoader) {

RandomValuePropertySource.addToEnvironment(environment);

  // 添加配置文件的屬性源

  new Loader(environment, resourceLoader).load();

}

RandomValuePropertySource

public static void 

addToEnvironment(ConfigurableEnvironment environment) {

  // 在 systemEnvironment 后面添加 random

  environment.getPropertySources().addAfter(

    StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,

    new RandomValuePropertySource(RANDOM_PROPERTY_SOURCE_NAME));

  logger.trace("RandomValuePropertySource add to Environment");

}

添加配置文件的屬性源:執(zhí)行

new Loader(environment, resourceLoader).load();,

調(diào)用 load(Profile, DocumentFilterFactory, DocumentConsumer)(getSearchLocations()

獲取配置文件位置,可以指定通過 spring.config.additional-location 、spring.config.location 、spring.config.name 參數(shù)或者使用默認(rèn)值 ), 然后調(diào)用 addLoadedPropertySources -> addLoadedPropertySource(加載 查找出來的 PropertySource 到 PropertySources,并確保放置到 defaultProperties 的前面 )

默認(rèn)的查找位置,配置為

"classpath:/,classpath:/config/,file:./,file:./config/",查找順序從后向前

PropertySources 順序:

  • commandLineArgs
  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment
  • random
  • application.properties ...
  • defaultProperties

1.3.3 SpringApplication#prepareContext

prepareContext 方法中,主要的三步如下

private void 

prepareContext(ConfigurableApplicationContext context,

              ConfigurableEnvironment environment,

              SpringApplicationRunListeners listeners,

              ApplicationArguments applicationArguments,

              Banner printedBanner) {

  ...

  applyInitializers(context); // 3.1

  listeners.contextPrepared(context); //3.2

  ...

  listeners.contextLoaded(context); // 3.3

}

1)applyInitializers 方法

會(huì)遍歷執(zhí)行所有的 ApplicationContextInitializer#initialize

擴(kuò)展點(diǎn)

自定義 ApplicationContextInitializer

2)listeners.contextPrepared 方法

會(huì)按優(yōu)先級(jí)順序遍歷執(zhí)行 SpringApplicationRunListener#contextPrepared,比如 EventPublishingRunListener 和 自定義的 SpringApplicationRunListener

擴(kuò)展點(diǎn)

自定義 SpringApplicationRunListener ,重寫 contextPrepared 方法

3)listeners.contextLoaded 方法

會(huì)按優(yōu)先級(jí)順序遍歷執(zhí)行 SpringApplicationRunListener#contextLoaded,比如 EventPublishingRunListener 和 自定義的 SpringApplicationRunListener

EventPublishingRunListener 發(fā)布

ApplicationPreparedEvent 事件

ConfigFileApplicationListener 監(jiān)聽

ApplicationEvent 事件 處理

ApplicationPreparedEvent 事件

擴(kuò)展點(diǎn)

  • 自定義 SpringApplicationRunListener ,重寫 contextLoaded 方法
  • 自定義 ApplicationListener ,監(jiān)聽 ApplicationPreparedEvent 事件

ConfigFileApplicationListener

@Override

public void onApplicationEvent(ApplicationEvent event) {

  // 處理 ApplicationEnvironmentPreparedEvent 事件

  if (event instanceof 

ApplicationEnvironmentPreparedEvent) {

    onApplicationEnvironmentPreparedEvent(

      (ApplicationEnvironmentPreparedEvent) event);

  }

  // 處理 ApplicationPreparedEvent 事件

  if (event instanceof ApplicationPreparedEvent) {

    onApplicationPreparedEvent(event);

  }

}

private void onApplicationPreparedEvent(ApplicationEvent event) {

  this.logger.replayTo(ConfigFileApplicationListener.class);

  addPostProcessors(((ApplicationPreparedEvent) event).getApplicationContext());

}

// 添加 PropertySourceOrderingPostProcessor 處理器,配置 PropertySources

protected void addPostProcessors(ConfigurableApplicationContext context) {

  context.addBeanFactoryPostProcessor(

    new PropertySourceOrderingPostProcessor(context));

}

PropertySourceOrderingPostProcessor

// 回調(diào)處理(在配置類屬性源解析)

@Override

public void 

postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

  throws BeansException {

  reorderSources(this.context.getEnvironment());

}

// 調(diào)整 PropertySources 順序,先刪除 defaultProperties, 再把 defaultProperties 添加到最后

private void reorderSources(ConfigurableEnvironment environment) {

  PropertySource

    .remove(DEFAULT_PROPERTIES);

  if (defaultProperties != null) {

    environment.getPropertySources().addLast(defaultProperties);

  }

}

PropertySourceOrderingPostProcessor 是 BeanFactoryPostProcessor

1.3.4 SpringApplication#refreshContext

會(huì)進(jìn)行 @Configuration 配置類屬性源解析,處理 @PropertySource annotations on your @Configuration classes,但順序是在 defaultProperties 之后,下面會(huì)把defaultProperties 調(diào)整到最后

AbstractApplicationContext#refresh 調(diào)用 invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors), 然后進(jìn)行 BeanFactoryPostProcessor 的回調(diào)處理 ,比如 PropertySourceOrderingPostProcessor 的回調(diào)(源碼見上文)

PropertySources 順序:

  • commandLineArgs
  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment
  • random
  • application.properties ...
  • @PropertySource annotations on your @Configuration classes
  • defaultProperties

(不推薦使用這種方式,推薦使用在 refreshContext 之前準(zhǔn)備好,@PropertySource 加載太晚,不會(huì)對(duì)自動(dòng)配置產(chǎn)生任何影響)

二、擴(kuò)展外部化配置屬性源

2.1 基于 EnvironmentPostProcessor 擴(kuò)展

public class CustomEnvironmentPostProcessor 

implements EnvironmentPostProcessor

2.2 基于 ApplicationEnvironmentPreparedEvent 擴(kuò)展

public class 

ApplicationEnvironmentPreparedEventListener implements ApplicationListener

2.3 基于 SpringApplicationRunListener 擴(kuò)展

public class CustomSpringApplicationRunListener implements SpringApplicationRunListener, Ordered

可以重寫方法 environmentPrepared、contextPrepared、contextLoaded 進(jìn)行擴(kuò)展

2.4 基于 ApplicationContextInitializer 擴(kuò)展

public class CustomApplicationContextInitializer implements ApplicationContextInitializer

關(guān)于與 Spring Cloud Config Client 整合,對(duì)外部化配置加載的擴(kuò)展(綁定到Config Server,使用遠(yuǎn)端的property sources 初始化 Environment),參考源碼PropertySourceBootstrapConfiguration(是對(duì) ApplicationContextInitializer 的擴(kuò)展)、ConfigServicePropertySourceLocator#locate

獲取遠(yuǎn)端的property sources是 RestTemplate 通過向 http://{spring.cloud.config.uri}/{spring.application.name}/{spring.cloud.config.profile}/{spring.cloud.config.label} 發(fā)送 GET 請(qǐng)求方式獲取的

2.5 基于 ApplicationPreparedEvent 擴(kuò)展

public class ApplicationPreparedEventListener 

implements ApplicationListener

2.6 擴(kuò)展實(shí)戰(zhàn)

2.6.1 擴(kuò)展配置

在 classpath 下添加配置文件 META-INF/spring.factories, 內(nèi)容如下

# Spring Application Run Listeners

org.springframework.boot.SpringApplicationRunListener=\

springboot.propertysource.extend.listener.CustomSpringApplicationRunListener

# Application Context Initializers

org.springframework.context.ApplicationContextInitializer=\

springboot.propertysource.extend.initializer.CustomApplicationContextInitializer

# Application Listeners

org.springframework.context.ApplicationListener=\

springboot.propertysource.extend.event.listener.ApplicationEnvironmentPreparedEventListener,\

springboot.propertysource.extend.event.listener.ApplicationPreparedEventListener

# Environment Post Processors

org.springframework.boot.env.EnvironmentPostProcessor=\

springboot.propertysource.extend.processor.CustomEnvironmentPostProcessor

以上的擴(kuò)展可以選取其中一種進(jìn)行擴(kuò)展,只是屬性源的加載時(shí)機(jī)不太一樣

2.6.2 擴(kuò)展實(shí)例代碼

https://github.com/shijw823/springboot-externalized-configuration-extend.git

PropertySources 順序:

propertySourceName: [ApplicationPreparedEventListener], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [CustomSpringApplicationRunListener-contextLoaded], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [CustomSpringApplicationRunListener-contextPrepared], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [CustomApplicationContextInitializer], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [bootstrapProperties], propertySourceClassName: [CompositePropertySource]

propertySourceName: [configurationProperties], propertySourceClassName: [ConfigurationPropertySourcesPropertySource]

propertySourceName: [CustomSpringApplicationRunListener-environmentPrepared], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [CustomEnvironmentPostProcessor-dev-application], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [ApplicationEnvironmentPreparedEventListener], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [commandLineArgs], propertySourceClassName: [SimpleCommandLinePropertySource]

propertySourceName: [servletConfigInitParams], propertySourceClassName: [StubPropertySource]

propertySourceName: [servletContextInitParams], propertySourceClassName: [ServletContextPropertySource]

propertySourceName: [systemProperties], propertySourceClassName: [MapPropertySource]

propertySourceName: [systemEnvironment], propertySourceClassName: [OriginAwareSystemEnvironmentPropertySource]

propertySourceName: [random], propertySourceClassName: [RandomValuePropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/springApplicationRunListener.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/applicationListener.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/applicationContextInitializer.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/environmentPostProcessor.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/application.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/extend/config/config.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [applicationConfig: [classpath:/application.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [springCloudClientHostInfo], propertySourceClassName: [MapPropertySource]

propertySourceName: [applicationConfig: [classpath:/bootstrap.properties]], propertySourceClassName: [OriginTrackedMapPropertySource]

propertySourceName: [propertySourceConfig], propertySourceClassName: [ResourcePropertySource]

propertySourceName: [defaultProperties], propertySourceClassName: [MapPropertySource]

bootstrapProperties 是 獲取遠(yuǎn)端(config-server)的 property sources

加載順序也可參考 http://{host}:{port}/actuator/env

PropertySources 單元測試順序:

  • @TestPropertySource#properties
  • @SpringBootTest#properties
  • @TestPropertySource#locations

三、參考資料

https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#boot-features-external-config

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

相關(guān)文章

  • Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問題詳解

    Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問題詳解

    這篇文章主要介紹了Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問題詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • hibernate關(guān)于session的關(guān)閉實(shí)例解析

    hibernate關(guān)于session的關(guān)閉實(shí)例解析

    這篇文章主要介紹了hibernate關(guān)于session的關(guān)閉實(shí)例解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 解決ObjectMapper.convertValue() 遇到的一些問題

    解決ObjectMapper.convertValue() 遇到的一些問題

    這篇文章主要介紹了解決ObjectMapper.convertValue() 遇到的一些問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java介紹多線程計(jì)算階乘實(shí)現(xiàn)方法

    Java介紹多線程計(jì)算階乘實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了Java多線程計(jì)算階乘的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word

    基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word

    這篇文章主要介紹了基于Freemarker和xml實(shí)現(xiàn)Java導(dǎo)出word,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java 在volatile內(nèi)部調(diào)用接口的方法

    Java 在volatile內(nèi)部調(diào)用接口的方法

    在Java中,volatile?關(guān)鍵字通常用于確保變量的可見性和有序性,而不是用來修飾接口或方法調(diào)用的,這篇文章主要介紹了Java 在volatile內(nèi)部調(diào)用接口的方法,需要的朋友可以參考下
    2024-07-07
  • ES結(jié)合java代碼聚合查詢詳細(xì)示例

    ES結(jié)合java代碼聚合查詢詳細(xì)示例

    es查詢有一個(gè)很常用的一種叫聚合查詢,相當(dāng)于mysql中的分組group by 后拿各組數(shù)量進(jìn)行統(tǒng)計(jì),實(shí)現(xiàn)起來也是很簡單,下面這篇文章主要給大家介紹了關(guān)于ES結(jié)合java代碼聚合查詢的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Spring學(xué)習(xí)筆記之bean的基礎(chǔ)知識(shí)

    Spring學(xué)習(xí)筆記之bean的基礎(chǔ)知識(shí)

    ean在Spring和SpringMVC中無所不在,將這個(gè)概念內(nèi)化很重要,所以下面這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)筆記之bean基礎(chǔ)的相關(guān)資料,文中通過示例代碼介紹的非常詳解,需要的朋友可以參考下。
    2017-12-12
  • java 8 lambda表達(dá)式中的異常處理操作

    java 8 lambda表達(dá)式中的異常處理操作

    這篇文章主要介紹了java 8 lambda表達(dá)式中的異常處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java中BM(Boyer-Moore)算法的圖解與實(shí)現(xiàn)

    Java中BM(Boyer-Moore)算法的圖解與實(shí)現(xiàn)

    本文主要介紹了兩個(gè)大的部分,第一部分通過圖解的方式講解BM算法,第二部分則代碼實(shí)現(xiàn)一個(gè)簡易的BM算法,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-05-05

最新評(píng)論

永福县| 绍兴市| 永泰县| 田林县| 拉萨市| 阳山县| 南汇区| 迁西县| 盐亭县| 广昌县| 鲜城| 昌宁县| 厦门市| 小金县| 鄂伦春自治旗| 安义县| 吉木乃县| 临汾市| 富源县| 黑龙江省| 崇州市| 宁国市| 从化市| 斗六市| 象山县| 衡东县| 个旧市| 喀喇| 赤峰市| 靖安县| 大竹县| 灵寿县| 南和县| 庄浪县| 临夏县| 安龙县| 聂拉木县| 察哈| 垫江县| 南宁市| 钟祥市|