Spring Boot外部化配置实战解析

简介: 源码解析Spring Boot外部化配置实战。

一、流程分析

1.1 入口程序

在 SpringApplication#run(String... args) 方法中,外部化配置关键流程分为以下四步

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

    }

    ...

}
AI 代码解读

1.2 关键流程思维导图

1.3 关键流程详解

对入口程序中标记的四步,分析如下

1.3.1 SpringApplication#getRunListeners

加载 META-INF/spring.factories

获取 SpringApplicationRunListener

的实例集合,存放的对象是 EventPublishingRunListener 类型 以及自定义的 SpringApplicationRunListener 实现类型

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;

}
AI 代码解读
1) getOrCreateEnvironment 方法

在 WebApplicationType.SERVLET web应用类型下,会创建 StandardServletEnvironment,本文以 StandardServletEnvironment 为例,类的层次结构如下

当创建 StandardServletEnvironment,StandardServletEnvironment 父类 AbstractEnvironment 调用 customizePropertySources 方法,会执行 StandardServletEnvironment#customizePropertySources和 StandardEnvironment#customizePropertySources ,源码如下AbstractEnvironment

public AbstractEnvironment() {

    customizePropertySources(this.propertySources);

    if (logger.isDebugEnabled()) {

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

    }

}
AI 代码解读

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

}
AI 代码解读

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

}
AI 代码解读

PropertySources 顺序:

  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment

PropertySources 与 PropertySource 关系为 1 对 N

2) configureEnvironment 方法

调用 configurePropertySources(environment, args), 在方法里面设置 Environment 的 PropertySources , 包含 defaultProperties 和

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

SimpleCommandLinePropertySource(commandLineArgs)到最前面

PropertySources 顺序:

  • commandLineArgs
  • servletConfigInitParams
  • servletContextInitParams
  • jndiProperties
  • systemProperties
  • systemEnvironment
  • defaultProperties
3) listeners.environmentPrepared 方法

会按优先级顺序遍历执行 SpringApplicationRunListener#environmentPrepared,比如 EventPublishingRunListener 和 自定义的 SpringApplicationRunListener

EventPublishingRunListener 发布

ApplicationEnvironmentPreparedEvent 事件

  • ConfigFileApplicationListener 监听

ApplicationEvent 事件 、处理 ApplicationEnvironmentPreparedEvent 事件,加载所有 EnvironmentPostProcessor 包括自己,然后按照顺序进行方法回调

---ConfigFileApplicationListener#postProcessEnvironment方法回调 ,然后addPropertySources 方法调用

RandomValuePropertySource#addToEnvironment,在 systemEnvironment 后面添加 random,然后添加配置文件的属性源(详见源码ConfigFileApplicationListener.Loader#load()

扩展点

  • 自定义 SpringApplicationRunListener ,重写 environmentPrepared 方法
  • 自定义 EnvironmentPostProcessor
  • 自定义 ApplicationListener 监听 ApplicationEnvironmentPreparedEvent 事件
  • ConfigFileApplicationListener,即是 EnvironmentPostProcessor ,又是 ApplicationListener ,类的层次结构如下

@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 进行优先级排序

    AnnotationAwareOrderComparator.sort(postProcessors);

    // 回调 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();

}
AI 代码解读

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

}
AI 代码解读

添加配置文件的属性源:执行

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

调用 load(Profile, DocumentFilterFactory, DocumentConsumer)(getSearchLocations()

获取配置文件位置,可以指定通过 spring.config.additional-location 、spring.config.location 、spring.config.name 参数或者使用默认值 ), 然后调用 addLoadedPropertySources -> addLoadedPropertySource(加载 查找出来的 PropertySource 到 PropertySources,并确保放置到 defaultProperties 的前面 )

默认的查找位置,配置为

"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

}
AI 代码解读
1)applyInitializers 方法

会遍历执行所有的 ApplicationContextInitializer#initialize

扩展点

  • 自定义 ApplicationContextInitializer
2)listeners.contextPrepared 方法

会按优先级顺序遍历执行 SpringApplicationRunListener#contextPrepared,比如 EventPublishingRunListener 和 自定义的 SpringApplicationRunListener

扩展点

自定义 SpringApplicationRunListener ,重写 contextPrepared 方法

3)listeners.contextLoaded 方法

会按优先级顺序遍历执行 SpringApplicationRunListener#contextLoaded,比如 EventPublishingRunListener 和 自定义的 SpringApplicationRunListener

EventPublishingRunListener 发布

ApplicationPreparedEvent 事件

  • ConfigFileApplicationListener 监听

ApplicationEvent 事件 处理

ApplicationPreparedEvent 事件

扩展点

  • 自定义 SpringApplicationRunListener ,重写 contextLoaded 方法
  • 自定义 ApplicationListener ,监听 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));

}
AI 代码解读

PropertySourceOrderingPostProcessor

// 回调处理(在配置类属性源解析)

@Override

public void 

postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

    throws BeansException {

    reorderSources(this.context.getEnvironment());

}

 

// 调整 PropertySources 顺序,先删除 defaultProperties, 再把 defaultProperties 添加到最后

private void reorderSources(ConfigurableEnvironment environment) {

    PropertySource

        .remove(DEFAULT_PROPERTIES);

    if (defaultProperties != null) {

        environment.getPropertySources().addLast(defaultProperties);

    }

}
AI 代码解读

PropertySourceOrderingPostProcessor 是 BeanFactoryPostProcessor

1.3.4 SpringApplication#refreshContext

会进行 @Configuration 配置类属性源解析,处理 @PropertySource annotations on your @Configuration classes,但顺序是在 defaultProperties 之后,下面会把defaultProperties 调整到最后

AbstractApplicationContext#refresh 调用 invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors), 然后进行 BeanFactoryPostProcessor 的回调处理 ,比如 PropertySourceOrderingPostProcessor 的回调(源码见上文)

PropertySources 顺序:

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

(不推荐使用这种方式,推荐使用在 refreshContext 之前准备好,@PropertySource 加载太晚,不会对自动配置产生任何影响)

二、扩展外部化配置属性源

2.1 基于 EnvironmentPostProcessor 扩展

public class CustomEnvironmentPostProcessor 

implements EnvironmentPostProcessor
AI 代码解读

2.2 基于 ApplicationEnvironmentPreparedEvent 扩展

public class 

ApplicationEnvironmentPreparedEventListener implements ApplicationListener
AI 代码解读

2.3 基于 SpringApplicationRunListener 扩展

public class CustomSpringApplicationRunListener implements SpringApplicationRunListener, Ordered
AI 代码解读

可以重写方法 environmentPrepared、contextPrepared、contextLoaded 进行扩展

2.4 基于 ApplicationContextInitializer 扩展

public class CustomApplicationContextInitializer implements ApplicationContextInitializer
AI 代码解读

关于与 Spring Cloud Config Client 整合,对外部化配置加载的扩展(绑定到Config Server,使用远端的property sources 初始化 Environment),参考源码PropertySourceBootstrapConfiguration(是对 ApplicationContextInitializer 的扩展)、ConfigServicePropertySourceLocator#locate

获取远端的property sources是 RestTemplate 通过向 http://{spring.cloud.config.uri}/{spring.application.name}/{spring.cloud.config.profile}/{spring.cloud.config.label} 发送 GET 请求方式获取的

2.5 基于 ApplicationPreparedEvent 扩展

public class ApplicationPreparedEventListener 

implements ApplicationListener
AI 代码解读

2.6 扩展实战

2.6.1 扩展配置

在 classpath 下添加配置文件 META-INF/spring.factories, 内容如下

# 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
AI 代码解读

以上的扩展可以选取其中一种进行扩展,只是属性源的加载时机不太一样

2.6.2 扩展实例代码

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 是 获取远端(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

作者:石建伟

来源:宜信技术学院

目录
打赏
0
0
0
0
485
分享
相关文章
Spring AI 实战|Spring AI入门之DeepSeek调用
本文介绍了Spring AI框架如何帮助Java开发者轻松集成和使用大模型API。文章从Spring AI的初探开始,探讨了其核心能力及应用场景,包括手动与自动发起请求、流式响应实现打字机效果,以及兼容不同AI服务(如DeepSeek、通义千问)的方法。同时,还详细讲解了如何在生产环境中添加监控以优化性能和成本管理。通过Spring AI,开发者可以简化大模型调用流程,降低复杂度,为企业智能应用开发提供强大支持。最后,文章展望了Spring AI在未来AI时代的重要作用,鼓励开发者积极拥抱这一技术变革。
748 71
Spring AI 实战|Spring AI入门之DeepSeek调用
|
3月前
|
深入解析 Spring Security 配置中的 CSRF 启用与 requestMatchers 报错问题
本文深入解析了Spring Security配置中CSRF启用与`requestMatchers`报错的常见问题。针对CSRF,指出默认已启用,无需调用`enable()`,只需移除`disable()`即可恢复。对于`requestMatchers`多路径匹配报错,分析了Spring Security 6.x中方法签名的变化,并提供了三种解决方案:分次调用、自定义匹配器及降级使用`antMatchers()`。最后提醒开发者关注版本兼容性,确保升级平稳过渡。
337 2
Spring AI与DeepSeek实战三:打造企业知识库
本文基于Spring AI与RAG技术结合,通过构建实时知识库增强大语言模型能力,实现企业级智能搜索场景与个性化推荐,攻克LLM知识滞后与生成幻觉两大核心痛点。
469 7
阿里云特惠云服务器99元与199元配置与性能和适用场景解析:高性价比之选
2025年,阿里云长效特惠活动继续推出两款极具吸引力的特惠云服务器套餐:99元1年的经济型e实例2核2G云服务器和199元1年的通用算力型u1实例2核4G云服务器。这两款云服务器不仅价格亲民,而且性能稳定可靠,为入门级用户和普通企业级用户提供了理想的选择。本文将对这两款云服务器进行深度剖析,包括配置介绍、实例规格、使用场景、性能表现以及购买策略等方面,帮助用户更好地了解这两款云服务器,以供参考和选择。
使用nps配置内网穿透加域名解析
使用nps配置内网穿透加域名解析
382 76
Spring Security 实战指南:从入门到精通
本文详细介绍了Spring Security在Java Web项目中的应用,涵盖登录、权限控制与安全防护等功能。通过Filter Chain过滤器链实现请求拦截与认证授权,核心组件包括AuthenticationProvider和UserDetailsService,负责用户信息加载与密码验证。文章还解析了项目结构,如SecurityConfig配置类、User实体类及自定义登录逻辑,并探讨了Method-Level Security、CSRF防护、Remember-Me等进阶功能。最后总结了Spring Security的核心机制与常见配置,帮助开发者构建健壮的安全系统。
196 0
Spring Boot 便利店销售系统项目分包设计解析
本文深入解析了基于Spring Boot的便利店销售系统分包设计,通过清晰的分层架构(表现层、业务逻辑层、数据访问层等)和模块化设计,提升了代码的可维护性、复用性和扩展性。具体分包结构包括`controller`、`service`、`repository`、`entity`、`dto`、`config`和`util`等模块,职责分明,便于团队协作与功能迭代。该设计为复杂企业级应用开发提供了实践参考。
136 0
构建企业级AI智能体(Spring AI Alibaba + JManus实战)
本内容深入探讨了基于Spring AI Alibaba 1.2 + JManus 0.9 + DeepSeek-V3等技术栈构建的电商客服工单智能处理系统。通过分析传统AI应用的三重困境,介绍了JManus智能体架构的核心突破,包括动态任务分解、状态持久化和服务热插拔等优势。同时详细展示了企业级环境配置、智能体行为设计及多智能体协作全流程,并提供了性能优化、生产部署与监控方案。最后,结合压力测试结果和调优策略,总结了企业级智能体设计原则与未来演进方向,为实现从“AI试验”到“AI生产”的转变提供了实践指导。
312 13
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
195 0
Spring Boot 3.x 现代化应用开发实战技巧与最佳实践
本指南基于Spring Boot 3.x,融合微服务、云原生与响应式编程等前沿技术,打造现代化应用开发实践。通过构建智能电商平台案例,涵盖商品、订单、用户等核心服务,展示Spring WebFlux、OAuth 2.0认证、Spring Cloud Gateway路由、GraalVM原生编译等技术实现。同时提供Docker/Kubernetes部署方案及性能优化策略,助您掌握从开发到生产的全流程。代码示例详实,适合进阶开发者参考。
103 2

推荐镜像

更多
  • DNS
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等

    登录插画

    登录以查看您的控制台资源

    管理云资源
    状态一览
    快捷访问