成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊如何手寫一個SpringBoot框架

開發 前端
在這篇文章中,我們將手寫模擬SpringBoot的核心流程,讓大家能夠以一種簡單的方式了解SpringBoot的大概工作原理。

你好,我是柳岸花開。

在這篇文章中,我們將手寫模擬SpringBoot的核心流程,讓大家能夠以一種簡單的方式了解SpringBoot的大概工作原理。

項目結構

我們創建一個工程,包含兩個模塊:

  1. springboot模塊,表示SpringBoot框架的源碼實現。
  2. user包,表示用戶業務系統,用來寫業務代碼來測試我們所模擬出來的SpringBoot。

首先,在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模塊下,我們進行正常的開發,比如先添加SpringBoot依賴,然后定義相關的Controller和Service:

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>springboot</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

定義UserController和UserService

在user包下定義UserController和UserService,希望能通過運行MyApplication中的main方法,直接啟動項目,并能在瀏覽器中正常訪問到UserController中的某個方法。

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("test")
    public String test(){
        return userService.test();
    }
}

核心注解和核心類:

  • @SpringBootApplication:這個注解加在應用啟動類上,即main方法所在的類。
  • SpringApplication:這個類中有個run()方法,用來啟動SpringBoot應用。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
public @interface BobSpringBootApplication {
}

public class BobSpringApplication {

    public static void run(Class clazz){
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(clazz);
        applicationContext.refresh();

        startTomcat(applicationContext);
    }

    private static void startTomcat(WebApplicationContext 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(context, "dispatcher", new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/", "dispatcher");

        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }

        tomcat.getServer().await();
    }
}

@BobSpringBootApplication
public class MyApplication {

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

實現Tomcat和Jetty的切換

如果項目中有Tomcat的依賴,那就啟動Tomcat;如果有Jetty的依賴就啟動Jetty;如果兩者都沒有則報錯;如果兩者都有也報錯。

public interface WebServer {
    void start();
}

public class TomcatWebServer implements WebServer {
    @Override
    public void start() {
        System.out.println("啟動Tomcat");
    }
}

public class JettyWebServer implements WebServer {
    @Override
    public void start() {
        System.out.println("啟動Jetty");
    }
}

模擬實現條件注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(BobOnClassCondition.class)
public @interface BobConditionalOnClass {
    String value() default "";
}

public class BobOnClassCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(BobConditionalOnClass.class.getName());
        String className = (String) annotationAttributes.get("value");

        try {
            context.getClassLoader().loadClass(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
}

模擬實現自動配置類:

@Configuration
public class WebServiceAutoConfiguration {
    @Bean
    @BobConditionalOnClass("org.apache.catalina.startup.Tomcat")
    public TomcatWebServer tomcatWebServer() {
        return new TomcatWebServer();
    }

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

在BobSpringApplication中添加獲取WebServer的方法:

public 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();
}

通過以上步驟,我們實現了一個簡單的SpringBoot,并且可以根據依賴切換Tomcat和Jetty。

責任編輯:武曉燕 來源: 柳岸花開
相關推薦

2024-06-17 11:59:39

2022-06-26 09:40:55

Django框架服務

2024-02-20 21:34:16

循環GolangGo

2021-08-27 07:06:10

IOJava抽象

2025-05-26 03:15:00

接口高可用框架

2025-02-28 08:46:24

框架微服務架構

2024-07-03 08:36:14

序列化算法設計模式

2023-08-10 08:28:46

網絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發模式

2022-05-24 08:21:16

數據安全API

2023-09-10 21:42:31

2024-09-09 00:00:00

編寫技術文檔

2023-04-03 00:09:13

2024-09-30 09:33:31

2024-11-27 16:07:45

2024-09-04 08:55:56

2021-10-14 11:08:17

大數據框架內存

2022-10-28 07:27:17

Netty異步Future

2022-11-12 12:33:38

CSS預處理器Sass
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产激情视频网站 | 日批的视频| 最新黄色毛片 | 91国内精品久久 | 亚洲国产一区二区三区在线观看 | 欧美激情va永久在线播放 | 亚洲一区二区在线视频 | 国产视频精品视频 | 午夜精品一区二区三区在线视频 | 日韩一区二区三区在线视频 | 欧美视频日韩 | 亚洲人成在线播放 | 卡通动漫第一页 | 欧美一区二区三区在线看 | 精品一二三区视频 | 特级黄色毛片 | 有码在线| 天天干天天操天天射 | 久久精品亚洲精品国产欧美 | 国产一区二区三区精品久久久 | 国产精品欧美一区二区三区不卡 | 国产一区二区三区高清 | 国产精品国产精品国产专区不卡 | 久久伊人免费视频 | 国产色黄 | 欧美中文字幕一区 | 黄网站在线播放 | 在线精品一区二区 | 成人在线免费视频 | 国产一区不卡在线观看 | 日本不卡一区 | 欧美日韩在线一区二区三区 | 精品久久久久久久久久久 | 精品国产一区二区三区久久久蜜月 | 日本a∨视频 | 久久久精品一区二区三区 | 国产高清视频在线 | 欧美日韩精品综合 | 久久在线视频 | 国产成年人视频 | 欧美日韩在线观看视频网站 |