欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot 原理(如何启动)

程序员文章站 2023-11-20 23:35:40
springboot 近年来很火,因为他的一些特性。springboot 特性官方原话:Create stand-alone Spring applications (能创建独立运行的应用)Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)(内嵌tomcat,jetty,underow容器)Provide opinionated 'starter' dependencies t....

springboot 近年来很火,因为他的一些特性。

springboot 特性

官方原话:

  • Create stand-alone Spring applications  (能创建独立运行的应用)

  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)(内嵌tomcat,jetty,underow容器)

  • Provide opinionated 'starter' dependencies to simplify your build configuration(能够编写自己的启动依赖通过简单配置)

  • Automatically configure Spring and 3rd party libraries whenever possible(自动集成spring或者第三方包)

  • Provide production-ready features such as metrics, health checks, and externalized configuration(提供生产特性,包括度量,健康检查等)

  • Absolutely no code generation and no requirement for XML configuration(无xml配置文件)

大概就是这些特性,极大的减少了XML配置和跟其他第三方集成这些痛病,让开发者只关注业务。

springboot 结构和依赖包

我们新建后的项目大概如下:pom


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

springboot 原理(如何启动)

一般我们pom文件只要引用spring-boot-starter-web,这个是springboot web项目的

spring-boot-starter-actuator这个是做服务器健康检查的依赖,

上图可以看到,spring-boot-starter-web(2.3.1)下又引入了spring-core(5.2.1) ,spring-web,spring-web-mvn,spring-boot-starter-tomcat等等,这里看出,其实springboot的底层还是spring-core,web模块用的还是springmvc

springboot 启动过程

下面是spring的启动类。

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

很简单的一个类,加了个@SpringBootApplication的注解,然后SpringApplication.run(DemoApplication.class, args);将本身类作为参数,然后就可以启动了。

首先 @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

ComponentScan这个注解是spring的注解,作用是扫描包(包就是当前类下的包以及包下的所有包)下所有加了一些spring注解的类,把这些类加载到bean容器中,比如@Component和@Repository等,还有@Configuration的类也会扫描到,把类中的bean注解也会加载到容器中。

EnableAutoConfiguration这个注解是springboot的注解

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

这个是springboot的自动装配的开关,springboot能够自动装配其他第三方包也是这个注解的作用。

通过@Import引入的一个AutoConfigurationImportSelector实例,这个实例里有一段代码

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

这个就是这个类的主要作用,作用就是加载我们项目路径下META-INF/spring.factories的文件,我们看看这些文件大概什么样?

springboot 原理(如何启动)

看到没有,这些就是springboot自动装配的原理和核心了,通过这个注解和AutoConfigurationImportSelector,启动时,spring就知道要初始化那些类,有些listener,还有那些配置类需要加载的。

很多第三方的jar包都是通过这种方式集成到我们的springboot的。随便找个第三方包

springboot 原理(如何启动)

本文地址:https://blog.csdn.net/shrek11/article/details/107080049