首页 > 其他分享 >手写SpringBoot(一)之简易版SpringBoot

手写SpringBoot(一)之简易版SpringBoot

时间:2024-03-29 13:58:39浏览次数:32  
标签:web SpringBoot springframework 简易版 import axj org 手写 cn

系列文章目录

手写SpringBoot(一)之简易版SpringBoot
手写SpringBoot(二)之动态切换Servlet容器
手写SpringBoot(三)之自动配置

手写SpringBoot(一)之简易版SpringBoot

  1. 添加依赖

    <?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">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.axj</groupId>
            <artifactId>spring-boot-base</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    
        <artifactId>my-spring-boot</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
    
        <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-aop</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>
    
    </project>
    
  2. 启动Spring容器

  • 定义MySpringBootApplication标识注解,对应SpringBootApplication
package cn.axj.springboot.my.annnotation;

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

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
public @interface MySpringBootApplication {
}

Configuration 注解表明该注解标注的类是一个配置类,在AnnotationConfigApplication 里面会解析这个类,并加载相应的容器bean

CompontScan 注解定义Configuration配置类下的扫描路径,如果不传,默认扫描标注类的包名。所以SpringBoot默认会扫描Application类下的当前包以及子包路径。

  • 定义MySpringApplication类,对应SpringApplication
package cn.axj.springboot.my.boot;

import cn.axj.springboot.my.web.container.WebContainer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;


public class MySpringApplication {

    public static void run(Class<?> clazz,String[] args) {
        //启动Spring容器
        AnnotationConfigWebApplicationContext annotationConfigApplicationContext = new AnnotationConfigWebApplicationContext();
        annotationConfigApplicationContext.register(clazz);
        annotationConfigApplicationContext.refresh();
        //启动tomcat容器
        WebContainer.startContainer(annotationConfigApplicationContext);
    }
}

  • register(clazz)通过传入的class对象扫描步骤二中Configuration和ComponentScan定义的路径地址,扫描组件注入到容器中。
  • 这里由于MySpringBootApplication注解是一个组合注解,包括@Configuration和@ComponentScan,Spring在获取到@MySpringBootApplication标注的类,会默认将该类作为配置类,所以这个@MySpringBootApplication不一定非得加到Application类上,可以专门定义一个Configuration类来标注,但是需要将该类Class作为参数传给MySpringApplication.run方法中。
  • 由于@Component默认会扫描被该注解标注的类的当前包路径作为默认扫描路径。所以@MySpringBootApplication标注的类的包路径需要注意。
  1. 启动tomcat

    启动tomcat

    配置DispatcherServlet

package cn.axj.springboot.my.web.container;

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.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public abstract class WebContainer{

    public static void startContainer(WebApplicationContext webApplicationContext){
        System.out.println("启动Web容器");
        Tomcat tomcat = new Tomcat();

        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");

        Connector connector = new Connector();
        connector.setPort(8080);

        StandardEngine 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,Springmvc专属
        tomcat.addServlet(contextPath,"dispatcher",new DispatcherServlet(webApplicationContext));
        context.addServletMappingDecoded("/*","dispatcher");


        try {
            tomcat.start();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
    }
}

至此,一个简易版的SpringBoot就完成了。

整个结构如下图所示

在这里插入图片描述

下面进行测试,新建一个user-service模块

  1. 引入自己写的springboot依赖
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.axj</groupId>
        <artifactId>spring-boot-base</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-service</artifactId>

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


    <dependencies>
        <dependency>
            <groupId>cn.axj</groupId>
            <artifactId>my-spring-boot</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  1. 在cn.axj.user下面创建UserApplication
package cn.axj.user;

import cn.axj.springboot.my.annnotation.MySpringBootApplication;
import cn.axj.springboot.my.boot.MySpringApplication;

@MySpringBootApplication
public class UserApplication {

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

  1. 新建controller层TestController
package cn.axj.user.controller;

import cn.axj.user.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class TestController {


    @Resource
    private UserService userService;

    @GetMapping("/test")
    public String test(){
        return userService.test();
    }
}
  1. 新建service层UserService
package cn.axj.user.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public String test(){
        return "hello";
    }
}
  1. 启动main方法
启动Web容器
三月 27, 2024 5:55:51 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8080"]
三月 27, 2024 5:55:51 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service [Tomcat]
三月 27, 2024 5:55:51 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet engine: [Apache Tomcat/9.0.75]
三月 27, 2024 5:55:52 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [322] milliseconds.
三月 27, 2024 5:55:52 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
三月 27, 2024 5:56:07 下午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring DispatcherServlet 'dispatcher'
三月 27, 2024 5:56:07 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
信息: Initializing Servlet 'dispatcher'
三月 27, 2024 5:56:08 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
信息: Completed initialization in 443 ms
三月 27, 2024 5:56:08 下午 org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping for GET /
三月 27, 2024 5:56:08 下午 org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping for GET /
三月 27, 2024 5:56:08 下午 org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping for GET /favicon.ico

至此项目启动完成

  1. 打开浏览器,访问localhost:8080/test,看到返回test字符串,代表成功

当我们想将tomcat换成jetty或者是underTow容器怎么实现呢?

标签:web,SpringBoot,springframework,简易版,import,axj,org,手写,cn
From: https://blog.csdn.net/aoxiaojun/article/details/137085129

相关文章

  • springboot部署在服务器上使用图片上传功能隔一段时间就会报错
    新写的一个项目,使用springboot实现上传图片的功能接口,然后刚开始部署在服务器上是正常使用的,但是隔一段时间就会发生上传失败,需要重新部署之后又正常,报错内容是Thetemporaryuploadlocation[/tmp/tomcat.7629195566189872429.5002/work/Tomcat/localhost/ROOT]isnotvalid......
  • 每日面经分享(SpringBoot part4:Controller层)
    SpringBootController层的作用a.请求映射:Controller层使用注解(如@RequestMapping、@GetMapping、@PostMapping等)将HTTP请求映射到相应的方法上。这些方法根据URL路径、请求方法、请求参数等来决定要执行的操作。b.参数解析:Controller层负责解析HTTP请求中的参数(如路径......
  • java毕业设计玩具租借系统(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在当今社会,随着人们生活水平的提升和消费观念的变化,儿童教育和娱乐逐渐成为家庭支出的重要部分。玩具作为儿童日常生活中不可或缺的元素,伴随着孩子的成长,......
  • java毕业设计微社区综合服务疫情防控管理系统(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:自新冠疫情爆发以来,社区作为疫情防控的第一线,承担着居民健康监测、防疫物资分配、疫情信息宣传等重要职责。传统的社区疫情防控多依赖人力进行,存在着信息......
  • java毕业设计无偿献血服务平台(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:无偿献血是一项社会公益活动,对于挽救生命、维护人类健康具有极其重要的意义。然而,在实际操作过程中,献血者往往面临信息不对称、献血地点不便、献血后服务......
  • java毕业设计企业员工自助管理系统(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在现代企业管理中,提高管理效率和员工满意度是企业发展的重要目标。随着企业规模的扩大和管理层次的增加,传统的人力资源管理方式已无法满足快速反应和高效......
  • 【毕业设计】基于springboot的大学生综合素质测评管理系统
    前言【毕业设计】大学生综测管理系统......
  • MybatisPlus多参数分页查询,黑马程序员SpringBoot3+Vue3教程第22集使用MP代替pagehelpe
    前言:视频来源1:黑马程序员SpringBoot3+Vue3全套视频教程,springboot+vue企业级全栈开发从基础、实战到面试一套通关视频来源2:黑马程序员最新MybatisPlus全套视频教程,4小时快速精通mybatis-plus框架创作理由:网上MP实现分页查询功能的帖子易读性太差,具体实现看下面。根据视频完成......
  • 免费分享一套SpringBoot+Vue个人健康管理系统,帅呆了~~
    大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue个人健康管理系统,分享下哈。项目视频演示【免费】SpringBoot+Vue个人健康管理系统Java毕业设计_哔哩哔哩_bilibili【免费】SpringBoot+Vue个人健康管理系统Java毕业设计项目来自互联网,免费开源分享,严禁商业。更多......
  • 【毕业设计】基于SpringBoot 和uniapp的食堂点餐系统
    效果源码下载文档一、概述由于互联网的飞速发展,饭店的点餐也要进行时代化的创新,由以前的人工点餐到现在的系统点单,大大减少了人力资源的利用。总体设计图由于互联网的飞速发展,饭店的点餐也要进行时代化的创新,由以前的人工点餐到现在的系统点单,大大减少了......