SpringBoot自动装配、启动流程及自定义starter

基于新张量核范数的TRPCA:多维数据低秩稀疏分解的理论与实践 本文深入探讨了基于新张量核范数的TRPCA(张量鲁棒主成分分析)技术。该技术通过t-product运算和新定义的张量核范数,能有效从多维数据(如视频、彩色图像)中分离低秩背景与稀疏前景/噪声。文章结合理论、核心算法(ADMM、t-SVT)及图像恢复、视频背景建模等实战案例,展示了其在处理复杂多维数据分解任务中的强大优势。 阅读详情

作为一名Java程序员,Spring框架是我们平常工作中非常重要的一个框架。其为我们提供了IOC容器和AOP的功能,在很大程度上简化了我们项目中的开发,但随着我们使用Spring接入的组件的增加,相应的配置文件也越来越多,这些配置文件的维护也成为了一个比较繁琐的工作,这也是很多开发人员比较诟病的地方。

SpringBoot的出现便很好的解决了这个问题,在SpringBoot项目中我们不再关注那么多的配置文件,其提供的自动装配功能使我们能够更容易的用其来快速的搭建我们的应用。

在今天的文章中我们就介绍下SpringBoot的自动装配、应用的启动流程,并在最后介绍下如何自定义一个starter。

1、示例代码

在介绍之前,我们先通过示例代码看看如何使用SpringBoot搭建一个web应用,示例代码使用的是SpringBoot的最新版本3.0.0,该版本依赖JDK17,如果本地使用的JDK8请使用低版本的SpringBoot或者升级JDK。

创建spring-boot-sample的maven项目并添加相关依赖,其pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xh</groupId>
    <artifactId>spring-boot-sample</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

在创建好的项目中编写一个启动类,其内容如下:

package com.xh.sample.spring.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description: Create by IntelliJ IDEA
 * @author: xh
 * @createTime: 2022/12/3 18:31
 */
@RestController
@SpringBootApplication
public class SpringBootSampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootSampleApplication.class, args);
    }

    @RequestMapping(value = "/hello")
    public String hello() {
        return "Hello World!!!";
    }
}

至此我们的示例代码就编写完成了,我们直接执行启动类中的main方法,启动完成后可以访问http://localhost:8080/hello进行测试。

我们在pom中引入了spring-boot-starter-web的依赖,便集成好了SpringMVC的功能,是不是很简单方便呢,这便是自动装配的魔力。

启动类中只需要添加@SpringBootApplication注解并调用SpringApplication.run方法即可,在下面的内容中我们主要就是围绕着这两点来进行介绍。

2、自动装配

自动装配是SpringBoot的核心,是基于Spring的注解及SPI机制进行的实现。当SpringBoot启动时会加载各个依赖包中META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(我们使用的是SpringBoot3.0.0版本,之前的版本中需要自动装配的类也是定义在spring.factories中的),并将该文件中配置的类加载到Spring容器中。

开启自动装配的逻辑关键在@SpringBootApplication这个注解上,这个注解的源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
  // 需要排除的类
  @AliasFor(annotation = EnableAutoConfiguration.class)
  Class<?>[] exclude() default {};

  @AliasFor(annotation = EnableAutoConfiguration.class)
  String[] excludeName() default {};
  // 扫描的包  默认是当前包路径
  @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
  String[] scanBasePackages() default {};

  @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
  Class<?>[] scanBasePackageClasses() default {};

  @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
  Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

  @AliasFor(annotation = Configuration.class)
  boolean proxyBeanMethods() default true;

}

从这段源码中我们可以看到@SpringBootApplication是一个复合注解;

  • @SpringBootConfiguration @Configuration的派生注解
  • @EnableAutoConfiguration 启用SpringBoot的自动装配
  • @ComponentScan Spring中的注意,用于扫描相应的包下被@Component及其派生注解修饰的类

因此,我们完全可以将这个注解替换为@Configuration、@EnableAutoConfiguration及@ComponentScan三个注解。

这里我们单独看下@EnableAutoConfiguration注解,其源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

  String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

  Class<?>[] exclude() default {};

  String[] excludeName() default {};

}

在这个注解中的@AutoConfigurationPackage注解的作用是将启动类所在包下的所有组件注册到Spring容器中,跟踪源码会发现其会调用到BeanDefinitionRegistry.register方法,这个是Spring中相关的类,我们这里就不展开了。

@Import注解中跟着的类,在Spring容器启动时会进行加载,这里面设置的是AutoConfigurationImportSelector,这个类的作用是加载自动装配类,这个类实现了DeferredimportSelector接口并实现了selectImports方法,这个方法的作用是收集所有需要加载到Spring容器中的类名。其逻辑如下:

public String[] selectImports(AnnotationMetadata annotationMetadata) {
  if (!isEnabled(annotationMetadata)) {
    return NO_IMPORTS;
  }
  AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
  return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
  // 是否开启了自动装配  判断的是spring.boot.enableautoconfiguration配置
  if (!isEnabled(annotationMetadata)) {
    return EMPTY_ENTRY;
  }
  // 获取注解的属性信息
  AnnotationAttributes attributes = getAttributes(annotationMetadata);
  // 获取所有需要自动装配的类
  List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
  // 移除重复的类
  configurations = removeDuplicates(configurations);
  // 移除需要排除的类
  Set<String> exclusions = getExclusions(annotationMetadata, attributes);
  checkExcludedClasses(configurations, exclusions);
  configurations.removeAll(exclusions);
  configurations = getConfigurationClassFilter().filter(configurations);
  fireAutoConfigurationImportEvents(configurations, exclusions);
  return new AutoConfigurationEntry(configurations, exclusions);
}

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  // 获取META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中配置的类
  List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
    .getCandidates();
  Assert.notEmpty(configurations,
                  "No auto configuration classes found in "
                  + "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
                  + "are using a custom packaging, make sure that file is correct.");
  return configurations;
}
// ImportCandidates类中的方法,LOCATION的值为:"META-INF/spring/%s.imports"
public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
  Assert.notNull(annotation, "'annotation' must not be null");
  ClassLoader classLoaderToUse = decideClassloader(classLoader);
  String location = String.format(LOCATION, annotation.getName());
  Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
  List<String> importCandidates = new ArrayList<>();
  while (urls.hasMoreElements()) {
    URL url = urls.nextElement();
    importCandidates.addAll(readCandidateConfigurations(url));
  }
  return new ImportCandidates(importCandidates);
}

到这里关于SpringBoot自动装配相关的逻辑已经介绍完了,通过查看源码的方式,我们可以知道:

  • @SpringBootApplication 是一个复合注解,拥有@Configuration、@EnableAutoConfiguration及@ComponentScan的功能
  • @EnableAutoConfiguration 是开启自动装配的注解,在其中定义了@Import(AutoConfigurationImportSelector.class)
  • AutoConfigurationImportSelector 类会在容器启动时获取到META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中配置的类交给Spring进行初始化

3、启动过程

在上面的内容中我们介绍了SpringBoot的自动装配的原理,在接下来的内容中我们介绍下SpringBoot的启动过程。自动装配的逻辑是在@SpringBootApplication中,其启动过程我们应该跟踪SpringApplication.run方法。

跟进这个源码会调用到如下的方法中:

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
  // 创建SpringApplication对象并调用run方法
  return new SpringApplication(primarySources).run(args);
}

SpringApplication对象的创建逻辑如下:

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
  // 这里传递的resourceLoader为null
  this.resourceLoader = resourceLoader;
  Assert.notNull(primarySources, "PrimarySources must not be null");
  // 这里的primarySources传递的是我们的启动类
  this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
  // 获取应用类型 NONE SERVLET REACTIVE 我们的示例代码是一个web项目  这里的类型是SERVLET
  this.webApplicationType = WebApplicationType.deduceFromClasspath();
  // 获取META-INF/spring.factories配置的BootstrapRegistryInitializer实例
  this.bootstrapRegistryInitializers = new ArrayList<>(
    getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
  // 获取META-INF/spring.factories配置的BootstrapRegistryInitializer实例
  setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
  // 获取META-INF/spring.factories配置的ApplicationListener实例
  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  this.mainApplicationClass = deduceMainApplicationClass();
}

在SpringApplication构造方法中设置应用类型并获取到一些在META-INF/spring.factories中配置的类实例。

应用类型有如下三种:

  • NONE
  • SERVLET
  • REACTIVE

getSpringFactoriesInstances方法最后会调用到SpringFactoriesLoader.load方法中,SpringFactoriesLoader类是Spring SPI的工具类,使用这个类可以获取到所有在META-INF/spring.factories中配置的信息并可按照某个类型获取实例列表。

通过这种方式获取对象的方法,都可以作为我们的扩展点,那么该如何使用呢?我们以BootstrapRegistryInitializer为例,我们在示例代码中定义一个SelfBootstrapRegistryInitializer类,创建META-INF/spring.factories文件并添加配置,代码如下:

public class SelfBootstrapRegistryInitializer implements BootstrapRegistryInitializer {
    @Override
    public void initialize(BootstrapRegistry registry) {
        System.out.println("=============== SelfBootstrapRegistryInitializer ==================");
    }
}
// spring.factories
org.springframework.boot.BootstrapRegistryInitializer=\
  com.xh.sample.spring.boot.SelfBootstrapRegistryInitializer

然后再重启项目,可以看到控制台会打印出我们输出的内容。

介绍完SpringApplication的构造方法后,我们看看这个对象中的run方法逻辑,这个方法中的逻辑就是启动SpringBoot的流程,其源码如下:

public ConfigurableApplicationContext run(String... args) {
  long startTime = System.nanoTime();
  //创建启动上下文对象  这里会调用在上面中获取到的BootstrapRegistryInitializer实例的initialize方法
  DefaultBootstrapContext bootstrapContext = createBootstrapContext();
  ConfigurableApplicationContext context = null;
  // 设置java.awt.headless属性
  configureHeadlessProperty();
  // 获取META-INF/spring.factories中配置的SpringApplicationRunListener实例
  // SpringApplicationRunListener里面提供了starting environmentPrepared contextPrepared 等方法
  // 使用这个扩展点可以完成对启动的各个阶段进行扩展
  SpringApplicationRunListeners listeners = getRunListeners(args);
  // 调用starting方法
  listeners.starting(bootstrapContext, this.mainApplicationClass);
  try {
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    // 准备环境
    ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
    // 打印banner图  如果自定义banner图的话 只需在resources目录下创建banner.txt文件即可
    Banner printedBanner = printBanner(environment);
    // 创建上下文对象 创建的是AnnotationConfigServletWebServerApplicationContext
    context = createApplicationContext();
    context.setApplicationStartup(this.applicationStartup);
    prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    // 启动容器的流程,这里会调用到AbstractApplicationContext.refresh方法中启动spring容器
    refreshContext(context);
    // 这里是个空方法,子类可以实现该方法做些扩展  模版方法
    afterRefresh(context, applicationArguments);
    Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
    if (this.logStartupInfo) {
      new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
    }
    // 容器启动成功  调用listeners的started方法
    listeners.started(context, timeTakenToStartup);
    // 从容器中获取所有的ApplicationRunner  CommandLineRunner对象  调用里面的run方法
    callRunners(context, applicationArguments);
  }
  catch (Throwable ex) {
    if (ex instanceof AbandonedRunException) {
      throw ex;
    }
    handleRunFailure(context, ex, listeners);
    throw new IllegalStateException(ex);
  }
  try {
    if (context.isRunning()) {
      Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
      listeners.ready(context, timeTakenToReady);
    }
  }
  catch (Throwable ex) {
    if (ex instanceof AbandonedRunException) {
      throw ex;
    }
    handleRunFailure(context, ex, null);
    throw new IllegalStateException(ex);
  }
  return context;
}

相应的逻辑在上面的备注中进行了介绍,通过跟踪源码,我们发现SpringBoot中也提供了很多扩展点,我们简单的梳理下如下:

  • 自定义BootstrapRegistryInitializer类 配置到spring.factories文件中
  • 自定义ApplicationContextInitializer类 配置到spring.factories文件中
  • 自定义ApplicationListener类 配置到spring.factories文件中
  • 自定义SpringApplicationRunListener类 配置到spring.factories文件中 用于扩展启动的各个阶段
  • 自定义banner图,在classpath下创建banner.txt文件
  • 自定义ApplicationRunner CommandLineRunner类,使用@Component交给spring容器管理,容器启动完成后调用其run方法

在我们之前的spring搭建的web项目,需要部署到tomcat或者其他的web服务容器中,但我们使用SpringBoot搭建的web应用只需执行一个SpringApplication.run方法便可对外提供web服务了,这是因为在SpringBoot中给我们内置了web容器,这块代码的逻辑在ServletWebServerApplicationContext.onRefresh方法中,看过spring容器启动源码的应该会发现,在容器启动完成后会调用这个方法。这里的代码就不进行粘贴了,在这里会创建WebServer对象,默认使用的是Tomcat,内容的容器有如下几种:

  • TomcatWebServer
  • JettyWebServer
  • NettyWebServer
  • UndertowWebServer
  • UndertowServletWebServer

3、自定义starter

在上面的内容中我们介绍了SpringBoot自动装配的逻辑,我们只需要按照他的规则便可以很方便的自定义一个starter。接下来的内容给出一个简单的示例。在示例代码中我们定义一个单机版redis的客户端redisson。

创建一个redisson-spring-boot-starter的Maven项目,并添加相关依赖如下:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot</artifactId>
  <version>3.0.0</version>
</dependency>

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>3.16.3</version>
</dependency>

创建RedissonProperties类,用于接收相关配置,内容如下:



@ConfigurationProperties(prefix = "redis")
public class RedissonProperties {
    private String host = "localhost";
    private Integer port = 6379;

    public String getHost() {
        return host;
    }

    public Integer getPort() {
        return port;
    }
}

创建RedissonAutoConfiguration类,内容如下:



@Configuration
@EnableConfigurationProperties(value = RedissonProperties.class)
public class RedissonAutoConfiguration {

    @Autowired
    private RedissonProperties redissonProperties;

    @Bean
    public RedissonClient redissonClient() {
        System.out.println("============= 初始化RedissonClient对象 ===============");
        Config config = new Config();
        config.useSingleServer().setAddress("redis://" + redissonProperties.getHost() + ":" + redissonProperties.getPort());

        return Redisson.create(config);
    }
}

 

在META-INF/spring目录下创建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,并将RedissonAutoConfiguration类配置进去,内容如下:



然后使用Maven install到本地仓库,在spring-boot-sample中引入其依赖,然后重启项目,可以在启动日志中看到我们打印的日志,代表我们自定义的starter可以正常使用了。

4、总结

今天的内容就这些了,在本文中介绍了SpringBoot的自动装配原理、启动过程及如何自定义starter。

本文中的示例代码使用的SpringBoot版本为3.0.0,JDK版本为17。

@SpringBootApplication是一个复合注解,是自动装配的关键,AutoConfigurationImportSelector会获取到项目中所有依赖包中META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中配置的类交给spring容器。

SpringBoot启动过程中会启动spring容器和web服务容器,并在其启动过程中有一些扩展点。

31.华为路由器:PPPOE配置模拟实验及NAT配置 实验环境 pppoe-client上面的接口信息 [AR1]dis ip interface brief *down: administratively down ^down: standby (l): loopback (s): spoofing The number of interface that is UP in Physical is 2 The number of interface that is DOWN in Physical is 1 The number of interface 阅读详情

相关推荐

DeepSeek研发的精算大模型「精卫」已实现98%精算任务覆盖,中国人寿采用后年节约3.2亿元技术采购成本,形成关键技术替代效应

根据现有资料,精算领域关键技术替代效应的行业标准定义尚未明确具体提及。然而,可以从相关文献中提取一些关键概念和方法来推导出可能的定义。​替代效应的基本定义​:替代效应是指一种商品价格变动引起另一种商品的相对价格变动,从而导致消费者在维持原有效用水平不变的条件下对商品需求量做出的调整。​技术替代效应​:在精算领域,技术替代效应可以理解为新技术或新方法对现有技术或方法的替代,从而影响精算模型、数据处理和决策过程。例如,机器学习在精算中的应用日益增长,改变了精算师的工作方式和模型构建方法。​。

百态·数智思维 | 聚焦大数据、量化与未来AI 1714

Springboot 自动装配流程分析

springboot自动装配流程分析

wdquan19851029的专栏 2349

STM32H750_QSPI_Flash_Configuration_With_CubeMX

本文详细介绍了如何使用STM32CubeMX配置STM32H750的QSPI Flash接口,包括硬件连接、CubeMX参数设置、代码生成与初始化流程优化。通过实战示例展示了Flash ID读取、页编程与数据读取等常用操作,并提供了调试技巧与性能优化建议,帮助开发者高效实现高速外部存储扩展。

weixin_29176179的博客 275

SpringBoot 自动装配流程以及核心源码剖析

Spring Framework 一直在致力于解决一个问题,就是如何让 bean 管理变得更简单,如何让开发者尽可能的少关注一些基础化的 bean 配置,从而实现自动装配。所谓的自动装配,实际上就是如何自动将 bean 装载到 Ioc 容器中来实际上在 spring 3.x 版本中,Enable 模块驱动注解的出现,已经有了一定的自动装配的雏形,而真正能够实现这一机制,还是在 spirng 4.x 版本中,conditional 条件注解的出现;

vnjohn 博主 > 主线分享后端领域业务设计知识、源码思想、架构设计 4008

立创开源便携式多生理参数监护仪:基于STM32H743与ADS1292R的心电血氧体温监测系统设计

本文详细解析了基于STM32H743与ADS1292R的便携式多生理参数监护仪开源设计。项目集成了心电、血氧和体温监测功能,采用模块化硬件架构,并重点介绍了利用FIR滤波和Pan-Tompkins算法进行心电信号处理的核心技术。文章提供了完整的复刻指南与避坑要点,是学习医疗电子设备设计的优秀实践案例。

weixin_30600615的博客 328

SPME/IP PPT详解

什么是中间件?它是操作系统与应用程序之间的一块代码,它对于应用程序提供了一些标准接口,屏蔽了应用程序与底层的一些交互,上层应用程序只要和中间件进行交互就可以了,这样就可以达到一个解耦的目的。SOMEIP其实是一个中间件,它是操作系统与应用程序之间的一段代码,它是可以运行在TCP/IP之上的,可以在很多平台上使用,可以适配较多的操作系统,可以提供很多接口。经过序列化之后,在网络上传输的是一些101010这样的二进制流。SOME/IP可以承接应用层的一些数据,进行打包放到传输层。

usstmiracle的博客 620

SpringBoot自动装配流程

Springboot的自动装配流程。

weixin_50519232的博客 5275

用 SAP Fiori Launchpad Content Manager 做目录传输:把 Catalog 变更稳稳送到目标系统

摘要:SAP Fiori项目中,目录传输是确保应用一致交付的关键环节。开发团队常遇到目录在不同系统/客户端间不一致的问题,核心在于理解Launchpad内容管理的两种作用域:系统级(/UI2/FLPCM_CONF)使用workbench请求跨系统传输,客户端级(/UI2/FLPCM_CUST)通过customizing请求按SCC4设置传输。混淆作用域会导致目录分叉,如系统级目录被客户端本地修改后形成独立副本。官方推荐使用Content Manager而非过时的Launchpad Designer,并强调手

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 106

SpringBoot的自动装配

SpringBoot自动装配原理

99Savage 5692

Ollama DNS 重新绑定攻击 (CVE-2024-28224)

一旦 DNS 重新绑定攻击成功,攻击者就可以对这些 API 进行排序,以读取 Ollama 运行的进程可访问的任意文件数据,并将这些数据泄露到攻击者控制的系统中。完成对“创建模型” API 请求的调用后,Ollama 将收集组成新创建的用户模型的许多工件,包括大型语言模型数据、许可证数据等,以及我们要提取的文件,所有这些都可以通过其 SHA256 内容进行寻址。这是我们要窃取的文件,在我们的示例中,是可通过运行 Ollama 的主机上的路径名访问的现有文本文件。值得注意的是,该模型配置为通过参数中的。

技术超强的网络安全平台 1648

File Load Error for Untitled.ipynb Unhandled error 解决方案

本文主要介绍了File Load Error for Untitled.ipynb Unhandled error 解决方案,希望能对使用jupyter notebook的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

一文搞懂SpringBoot启动流程及自动装配

Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包。你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter。

good___lucky的博客 3838

【某音电商】protobuf聊天协议逆向

某音电商私信、聊天消息protobuf协议逆向分析与解析

吴秋霖的博客 2318

SpringBoot自动装配原理与启动流程深度解析:从条件注解到自定义Starter

SpringBoot作为Java领域主流的微服务开发框架,其“约定优于配置”的设计理念极大简化了项目搭建与部署。理解其底层机制,尤其是自动装配与条件注解的协作原理,是突破API使用层面、掌握框架内核的关键。本文从SpringBoot的三大核心机制切入,剖析了@SpringBootApplication组合注解、SpringApplication启动流程中环境准备与容器刷新、以及基于@Conditional的条件装配逻辑;同时梳理了配置文件优先级、内嵌Web容器等工程实践要点。通过拆解自定义Starter的编

weixin_31528001的博客 271

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SpringBoot篇(自动装配原理)

自动装配简单来说就是自动把第三方组件的bean加到IOC容器里,在springboot项目中可以通过在启动类上加@SpringBootApplication注解来实现自动装配,这个注解是一个组合注解,真正实现自动装配的注解是步骤一:main方法中SpringApplication.run(xxx.class,args)的执行流程中有refreshContext(context)。

m0_74823827的博客 958

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

《Spring源码深度解析 郝佳 第2版》SpringBoot体系分析、Starter的原理

往期博客 《Spring源码深度解析 郝佳 第2版》容器的基本实现与XML文件的加载 《Spring源码深度解析 郝佳 第2版》XML标签的解析 《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决 《Spring源码深度解析 郝佳 第2版》ApplicationContext 《Spring源码深度解析 郝佳 第2版》AOP 《Spring源码深度解析 郝佳 第2版》JDBC、MyBatis原理 目录 ...

xiaosi的博客 1172

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

02原理篇(D2_SpringBoot 自动装配原理)

自动装配简单来说就是自动把第三方组件的bean加到IOC容器里,在springboot项目中可以通过在启动类上加@SpringBootApplication注解来实现自动装配,这个注解是一个组合注解,真正实现自动装配的注解是@EnableAutoConfiguration。步骤一:main方法中SpringApplication.run(xxx.class,args)的执行流程中有而这个refreshContext(context)内部会解析,配置类上自动装配功能的注解。

m0_74825409的博客 989

深入理解SpringBoot启动流程(包含自动装配和自定义starter是如何被实现)

SpringBoot启动流程

m0_48358308的博客 901

SpringBoot自动装配原理深度解析:从@SpringBootApplication到自定义Starter

自动装配是现代Java框架实现“约定优于配置”理念的核心机制,它通过类路径扫描和条件判断自动组装应用组件。其原理基于Java的SPI扩展机制,结合丰富的条件注解实现精准的依赖注入。这一技术显著提升了开发效率,减少了样板代码,使得开发者能够专注于业务逻辑实现。在微服务架构和模块化开发场景中,自动装配思想被广泛应用于功能模块的动态加载与多环境适配。本文以SpringBoot为例,深入剖析了@SpringBootApplication注解的复合结构、spring.factories文件的注册机制,以及@Condi

weixin_32821533的博客 268

SpringBoot如何自定义启动器

提高:自定义starter 启动器模块是一个 空 jar 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库; 命名方式: 官方命名: spring-boot-starter-xxx ,比如:spring-boot-starter-web… 自定义命名: xxx-spring-boot-starter ,比如:mybatis-spring-boot-starter 1、在idea中新建个空工程spring-boot-starter-diy 建完以后里面什么都没有 2、新建一个普通M

weixin_49149614的博客 718
上一篇: SpringSecurity的使用:为我们应用增加安全防护
下一篇: 前后端分离的项目,精确到按钮级别的权限控制如何做?
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值