手写Springboot核心流程

这篇具有很好参考价值的文章主要介绍了手写Springboot核心流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

Springboot启动流程

核心代码

验证效果


Springboot启动流程

  1. 创建Spring容器, 扫描并启动
  2. 容器选择Tomcat/Jetty
  3. 创建DispatchServlet, 与spring容器绑定
  4. 将DispatchServlet添加到Tomcat
  5. 启动Tomcat

核心代码

1. 首先, 创建两个module

手写Springboot核心流程,springboot

 2. maven依赖

springboot模块依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.18</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.60</version>
        </dependency>
    </dependencies>

user模块依赖

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springboot</artifactId>
            <version>1.0-SNAPSHOT</version>
<!--            <exclusions>
                <exclusion>
                    <artifactId>tomcat-embed-core</artifactId>
                    <groupId>org.apache.tomcat.embed</groupId>
                </exclusion>
            </exclusions>-->
        </dependency>
<!--        切换netty-->
<!--        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.43.v20210629</version>
        </dependency>-->

3. springboot核心配置类 

public class KkSpringApplication {

    /*
        1. 创建Spring容器
        2. 创建Tomcat
        3. 创建DispatchServlet, 与spring容器绑定
        4. 将DispatchServlet添加到Tomcat
        5. 启动Tomcat
     */
    public static void run(Class clazz) {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(clazz);
        applicationContext.refresh();
        WebServer webServer = getWebServer(applicationContext);
        webServer.start(applicationContext);
    }

    private static WebServer getWebServer(AnnotationConfigWebApplicationContext applicationContext) {
        Map<String, WebServer> map = applicationContext.getBeansOfType(WebServer.class);
        if (map.isEmpty()) {
            throw new NullPointerException();
        }
        if (map.size() > 1) {
            throw new IllegalStateException();
        }
        return map.values().stream().findFirst().get();
    }
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
@Import(KkImportSeclet.class)
public @interface KkSpringBootApplication {

}

4. Import自动配置类

public class KkImportSeclet implements DeferredImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 自动配置
        ServiceLoader<AutoConfiguration> loader = ServiceLoader.load(AutoConfiguration.class);
        List<String> list = new ArrayList<>();
        for (AutoConfiguration configuration : loader) {
            list.add(configuration.getClass().getName());
        }
        return list.toArray(new String[0]);
    }
}
@Configuration
public class WebServerAutoConfiguration implements AutoConfiguration{

    @Bean
    @ConditionalOnClass("org.apache.catalina.startup.Tomcat")
    public TomcatWebServer tomcatWebServer(){
        return new TomcatWebServer();
    }

    @Bean
    @ConditionalOnClass("org.eclipse.jetty.server.Server")
    public JettyWebServer jettyWebServer(){
        return new JettyWebServer();
    }
}

public interface AutoConfiguration {
}

 spi注入自动配置类. 资源目录创建文件

手写Springboot核心流程,springboot

5. 条件注解

public class KkCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionalOnClass.class.getName());
        String className = (String) annotationAttributes.get("value");
        try {
            context.getClassLoader().loadClass(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }

    }
}
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(KkCondition.class)
public @interface ConditionalOnClass {

    String value();
}

6. Tomcat启动类实现

public class TomcatWebServer implements WebServer{
    @Override
    public void start(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);

        tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*", "dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
        System.out.println("启动Tomcat ... ");
    }
}

7. User模块使用自定义springboot组件

@KkSpringBootApplication
public class MyApplication {

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

验证效果

1. 启动MyApplication

手写Springboot核心流程,springboot

 2. 调test接口

手写Springboot核心流程,springboot文章来源地址https://www.toymoban.com/news/detail-790501.html

到了这里,关于手写Springboot核心流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot:手写一个 SpringBoot Starter

    声明:原文作者:yuan_404 启动器模块是一个 空 jar 文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库 命名归约: 官方命名: 前缀:spring-boot-starter-xxx 比如:spring-boot-starter-web… 自定义命名: xxx-spring-boot-starter 比如:mybatis-spring-boot-starter 在IDEA中新建一

    2024年02月03日
    浏览(32)
  • 手写springBoot启动器

    提示:springboot原理,手写springboot启动器,手写模拟SpringBoot启动过程、手写模拟SpringBoot自动配置功能 大家都知道springboot号称“手脚架”,用默认大于配置的方式,方便我们放弃写冗余复杂的配置文件。但了解的可能不是那么深刻,具体的执行过程,也没有那么清晰。通过手

    2024年01月17日
    浏览(40)
  • 手写springboot

    内嵌tomcat spi技术动态加载 1. 建一个工程目录结构如下: 2.springboot工程项目构建 1. pom依赖如下 2. SpringBoot时,核心会用到SpringBoot一个类和注解: @SpringBootApplication,这个注解是加在应用启动类上的,也就是main方法所在的类 SpringApplication,这个类中有个run()方法,用来启动Spr

    2024年02月14日
    浏览(23)
  • 手写一个starter来理解SpringBoot的自动装配

    自动装配是指SpringBoot在启动的时候会自动的将系统中所需要的依赖注入进Spring容器中 我们可以点开 @SpringBootApplication 这个注解来一探究竟 点开这个注解可以发现这些 我们点开 @SpringBootConfiguration 这个注解 可以发现实际上 @SpringBootApplication 这个其实是一个配置类 再点开 @En

    2024年01月23日
    浏览(41)
  • 手写SpringBoot3的starter及git高级用法

    新版Spring Boot3.X和旧版SpringBoot2.7之前自定义Starter区别 - SpringBoot2.7之前 META-INF/spring.factories文件里添加org.springframework.boot.autoconfigure.EnableAutoConfiguration=XXAutoConfiguration - SpringBoot2.7推出新的自动配置 在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件里添加配置类

    2024年02月01日
    浏览(37)
  • 手写自己的Springboot-2-从Servlet容器选择彻底理解自动配置

    如果还没有看第一篇文章的伙伴,建议先看第一篇文章 手写自己的Springboot-1-整合tomcat,该文章在第一篇文章基础上进行扩展. 在我们使用Springboot时,如果不想用Tomcat,想用Jetty,应该怎么办呢? 其实很简单,我们只需要把Tomcat的依赖排除掉,然后引入Jetty即可. 那Springboot底层究竟是怎样

    2024年02月05日
    浏览(38)
  • SpringBoot-面试核心概念

    目录 引言: 1.什么是SpringBoot,Spring,SpringMVC以及它们的区别? 2.SpringBoot的核心注解有哪些? 3.SpringBoot的Starter有哪些? 4.SpringBoot的配置文件有哪些? 5.SpringBoot的优点? 6.SpringBoot的运行方式 7.什么是JavaConfig 8.SpringBoot 实现热部署有哪几种方式? 9.SpringBoot自动配置的原理 10.S

    2024年02月08日
    浏览(69)
  • 79.SpringBoot的核心注解

    @SpringBootApplication注解:这个注解标识了一个SpringBoot工程,它实际上是另外三个注解的组合,这三个注解是: @SpringBootConfiguration:这个注解实际就是一个@Configuration,表示启动类也是一个配置类 @EnableAutoConfiguration:向Spring容器中导入了一个Selector,用来加载ClassPath下SpringFact

    2024年02月22日
    浏览(35)
  • SpringBoot核心内容梳理

    Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它简化了Spring应用程序的创建和开发过程,使开发人员能够更快速地创建独立的、生产就绪的Spring应用程序。它采用了“约定优于配置”的原则,尽可能地减少开发人员需要进行手动配置的步骤,提供了自动配置和快

    2024年02月14日
    浏览(34)
  • SpringBoot官方笔记3核心

    By default,  INFO  logging messages are shown, including some relevant startup details, such as the user that launched the application. Lazy Initialization When lazy initialization is enabled, beans are created as they are needed rather than during application startup. @Lazy(false)  annotation:disable lazy initialization for certain beans Customizing th

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包