Springboot 简单原理分析

  1. 不同于spring MVC,springboot是内嵌服务器。spring MVC需要依靠tomcat来启动,而springboot不需要,两者的启动顺序不同。

  2. spring MVC是先启动tomcat服务器 ,在创建spring容器,springboot是先创建spring容器,在启动tomcat服务器。

springboot流程

  1. new SpringApplication():创建SpringApplication实例,负责加载配置一些基本的环境变量、资源、构造器、监听器
  2. run():负责springboot整个启动过程,包括加载创建环境、打印banner、配置文件、配置应用上下文,加载bean等等springboot整个生命周期几乎都在run方法中;

手写一个极简@SpringbootApplication注解

  1. 创建一个含@Component和@ComponentScan的注解类。
  2. 创建一个启动类,内容包括spring容器创建和tomcat容器创建和启动,并将spring容器添加只servlet中
  3. 用@Bean方式创建一个dispatcherServlet。(此处可随意)

示例:

1.注解PrincipleSpringBootApplication:

package springBoot.principle.boot;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@ComponentScan      //ComponentScan默认扫描注解类所在的包
public @interface PrincipleSpringBootApplication {
}

2.启动类PrincipleSpringApplication :

package springBoot.principle.boot;

import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * springboot主要实现方式
 */
public class PrincipleSpringApplication {

    public static ConfigurableApplicationContext run(Class config) {
        //创建annotation形式的spring web容器,继承自AbstractApplicationContext
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(config);
        applicationContext.refresh();//Spring创建容器的核心方法
        startTomcat(applicationContext);
        return applicationContext;
    }

    /**
     * Tomcat启动方法,主要都是添加tomcat启动所需的配置
     *
     * @param applicationContext
     */
    private static void startTomcat(AnnotationConfigWebApplicationContext applicationContext) {
        Tomcat tomcat = new Tomcat();
        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");
        Connector connector = new Connector();
        connector.setPort(8081);
        Engine engine = new StandardEngine();
        engine.setDefaultHost("localhost");
        Host host = new StandardHost();
        host.setName("localhost");
        String contextPath = "";
        Context context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());
        host.addChild(context);
        engine.addChild(host);
        service.setContainer(engine);
        service.addConnector(connector);
        //创建dispatcherServlet,并将spring容器bean添加到servlet中
        //DispatcherServlet bean=new DispatcherServlet(applicationContext);
        DispatcherServlet servlet = applicationContext.getBean(DispatcherServlet.class);
        //配置servlet映射
        tomcat.addServlet(contextPath, "dispatcher", servlet);
        context.addServletMappingDecoded("/*", "dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }

}

3.使用@PrincipleSpringBootApplication并自定义一个dispatcherServlet

package springBoot.principle;

import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.DispatcherServlet;
import springBoot.principle.boot.PrincipleSpringApplication;
import springBoot.principle.boot.PrincipleSpringBootApplication;

@PrincipleSpringBootApplication
public class SpringBootTest {

    @Bean
        public DispatcherServlet dispatcherServlet(){
        DispatcherServlet dispatcherServlet=new DispatcherServlet();
        //提供可供自定义编辑的dispatcherServlet,此处可自行添加其他逻辑
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        return dispatcherServlet;
    }

    public static void main(String[] args) {
        PrincipleSpringApplication.run(SpringBootTest.class);
    }

}

springboot的自动配置

  1. springboot采用的约定配置的方式,即按现有的开发习惯来定义好spring mvc中需要的配置。
  2. 在springboot核心模块springboot starter中引入了springboot autoconfigure模块,而在autoconfigure的resources中有spring.factories文件,其中包含了springboot的所有配置类,在springboot启动时通过类SPI方式启动,将所有的配置都当作bean存入spring容器中。

可参考源码进行相应的修改:SpringFactoriesLoader中的loadSpringFactories()方法

  1. 例如默认端口号8080就在AbstractConfigurableWebServerFactory中被定义。

配置文件application.yml的加载方式

  1. 通过debug可知,入口在SpringApplication中的prepareEnvironment方法。
  2. 最后在ConfigFileApplicationListener中的addPropertySources方法中。

Server属性的配置读取在ServletFactoryCustomize.java中的customize()方法中,在BeanPostProcessor中传递进来。

application.yml中服务器server有关的加载内容在ServerProperties.java中。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值