SpringBoot源码简易篇

简介: SpringBoot源码简易篇

通过手写模拟SpringBoot源码了解其中的逻辑原理,自动配置,整合Tomcat,启动过程等。

目录

启动类

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

MySpringBootApplication注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
@Import(AutoConfigurationImportSelector.class)
public @interface MySpringBootApplication {
}

SpringApplication类

public class SpringApplication {
    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(ApplicationContext applicationContext){
        Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);
       if(webServers.isEmpty()){
           throw new NullPointerException();
       }
       if(webServers.size()>1){
           throw new IllegalStateException();
       }
        return webServers.values().stream().findFirst().get();
    }
}

WebServerAutoConfiguration类

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

TomcatWebServer类

public class TomcatWebServer implements WebServer{
     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);
        //Springmvc
        tomcat.addServlet(contextPath,"dispatcher",new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*","dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }
}

MyCondition 类

public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnClass.class.getName());
        String className= (String) annotationAttributes.get("value");
        try {
            Class<?> aClass = conditionContext.getClassLoader().loadClass(className);
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }
}

ConditionalOnClass注解

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyCondition.class)
public @interface ConditionalOnClass {
    String value();
}

AutoConfigurationImportSelector类

public class AutoConfigurationImportSelector implements DeferredImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        //jdk SPI
        ServiceLoader<AutoConfiguration> serviceLoader = ServiceLoader.load(AutoConfiguration.class);
        List<String> list=new ArrayList<>();
        for (AutoConfiguration autoConfiguration : serviceLoader) {
            list.add(autoConfiguration.getClass().getName());
        }
        return list.toArray(new String[0]);
    }
}

文件源码下载地址在我的文件资源:https://download.csdn.net/download/qq_43649937/87521102

番外篇


由于文字代码太多,文字太少,这里写个java学习路线总结


对于想要学习Java编程语言的人来说,制定学习路线是非常重要的。在这篇文章中,我将为您提供一个基础的Java学习路线,帮助您更快地掌握Java编程语言。


Java 基础


首先,您需要了解Java基础知识。这些知识包括Java语法、变量和数据类型、运算符、流程控制语句、数组、类和对象等。这个阶段最好通过阅读一些Java入门书籍或者在线教程来学习。我的建议是,如果您已经有编程经验,可以选择一些更深入的学习资源,例如《Java核心技术》或者《Thinking in Java》。


面向对象编程


Java 是一种面向对象的程序设计语言。因此,在学习Java时,必须熟悉面向对象编程思想。这个阶段,您应该学习对象、类、封装、继承、多态等面向对象编程的概念。我的建议是在学习Java的同时,也可以去学习其他语言的面向对象编程,如C++或Python等。


Java 集合框架


Java集合框架是Java中最重要的部分之一。它包括了Java中大部分用于数据存储和处理的类和接口。了解集合框架非常重要,因为它们是您在编写Java程序时必须使用的最常见工具之一。我的建议是学习ArrayList、LinkedList、HashMap、HashSet等基本的集合类。


Java 输入输出流


在Java编程中,输入输出流是必不可少的。Java提供了各种各样的类和接口来访问文件、网络和其他设备上的数据。这个阶段,您应该学习如何使用Java的输入输出流来读取和写入文件、网络连接和其他数据源。我的建议是学习Java.io包中的InputStream和OutputStream类。


Java 网络编程


Java 是一个广泛用于网络编程的语言。了解Java网络编程对于开发网络应用程序非常重要。这个阶段,您应该去了解Java网络编程所需要的Socket编程、TCP协议和UDP协议。我的建议是跟随一些使用Java进行网络编程的教程学习,例如《Java网络编程》或者《Head First Java》。


Java 多线程编程


Java 实现多线程编程非常容易,并且可以有效地提高程序的性能。了解多线程编程对于开发复杂的应用程序至关重要。这个阶段,您应该学习Java中的线程模型、线程安全、同步和锁等概念。我的建议是学习Java中的Thread类和Runnable接口。


Java 数据库编程


Java 与数据库的连接对于许多应用程序来说是至关重要的。Java提供了一个称为JDBC(Java Database Connectivity)的API,它允许您使用Java编写与各种关系型数据库进行交互的应用程序。这个阶段,您应该学习如何使用JDBC API来连接数据库、执行SQL语句和处理结果集。我的建议是学习Java中的JDBC技术。


Servlet 和 JSP


Servlet 和 JSP 是Java Web开发的基础。Servlet 允许在Web服务器上运行Java代码,而JSP 允许您在HTML文档中嵌入Java代码。这个阶段,您应该学习如何编写Servlet和JSP以及如何将它们部署到Web服务器上。我的建议是学习Java EE平台相关的知识,如Tomcat或者其他应用服务器。


SSM ,Springboot, Springcloud等框架


Spring 是一个非常流行的Java应用程序开发框架。它提供了大量的组件和工具,以帮助您更轻松地编写高质量的Java应用程序。Spring家族非常强大。


总结


以上就是基础的Java学习路线总结。学习Java需要长时间的投入和练习,但如果您按照上述路线进行学习,您将能够快速地掌握Java编程语言并开始开发自己的Java应用程序。记住,不要害怕犯错,不断尝试和实践,这是成为一名优秀Java程序员的关键。

相关文章
|
3月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
163 5
|
4月前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
128 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
4月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
633 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
1月前
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
136 36
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
61 10
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
46 8
|
26天前
|
JavaScript 搜索推荐 Java
基于SpringBoot+Vue实现的家乡特色推荐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 8
|
26天前
|
JavaScript NoSQL Java
基于SpringBoot+Vue实现的大学生就业服务平台设计与实现(系统源码+文档+数据库+部署等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
67 6
|
26天前
|
JavaScript Java 测试技术
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 6
|
26天前
|
JavaScript NoSQL Java
基于SpringBoot+Vue的班级综合测评管理系统设计与实现(系统源码+文档+数据库+部署等)
✌免费选题、功能需求设计、任务书、开题报告、中期检查、程序功能实现、论文辅导、论文降重、答辩PPT辅导、会议视频一对一讲解代码等✌
40 4