10 -【 SpringBoot 实现原理 】

1 什么是 SpringBoot

Spring Boot 让我们的 Spring 应用变的更轻量化。比如:你可以仅仅依靠一个 Java 类来运行一个 Spring 引用。你也可以打包你的应用为 jar 并通过使用 java -jar 来运行你的 Spring Web 应用。

Spring Boot 的主要优点:

  • 为所有 Spring 开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化 Web 项目
  • 没有冗余代码生成和 XML 配置的要求

SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化 XML 配置,全部采用注解形式,内置 Tomcat 容器,帮助开发者能够实现快速开发,SpringBoot 的 Web 组件 默认集成的是 SpringMVC 框架。

SpringMVC 是控制层。

1.1 SpringBoot 核心原理

基于 SpringMVC 无配置文件(纯Java)完全 注解化+内置tomcat-embed-core 实现 SpringBoot 框架,Main 函数启动。

SpringBoot 核心快速整合第三方框架原理:Maven 继承依赖关系。

SpringBoot 内嵌入 tomcat-embed-core

SpringBoot 采用 SpringMVC 注解版本实现无配置效果。

2 实现内置 Tomcat 容器

Java 提供内置 Tomcat 容器框架,使用 Java 语言操作 Tomcat 容器。

案例:使用 Java 语言创建一个 Tomcat 容器。

2.1 Maven 依赖

<dependencies>
    <!--Java语言操作tomcat -->
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>8.5.16</version>
    </dependency>
    <!-- spring-web -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.0.4.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <!-- spring-mvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.4.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <!-- tomcat对jsp支持 -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jasper</artifactId>
        <version>8.5.16</version>
    </dependency>
</dependencies>

2.2 创建 Servlet 类

package com.snow.servlet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class IndexServet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().print("springboot2.0");
    }
}

2.3 创建 Tomcat 运行

package com.snow.tomcat;

import com.snow.servlet.IndexServet;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;

/**
 * 使用 Java 创建 Tomcat 服务器
 *
 */
public class Test {

    // 端口号
    private static int PORT = 8080;
    // 项目名称
    private static String CONTEXTPATH = "/snow";

    public static void main(String[] args) throws LifecycleException {
        // 创建Tomcat服务器
        Tomcat tomcatServer = new Tomcat();
        // 设置Tomcat端口号
        tomcatServer.setPort(PORT);
        tomcatServer.getHost().setAutoDeploy(false);
        // 创建Context上下文
        StandardContext standardContext = new StandardContext();
        standardContext.setPath(CONTEXTPATH);
        standardContext.addLifecycleListener(new Tomcat.FixContextListener());
        // tomcat容器添加standardContext
        tomcatServer.getHost().addChild(standardContext);
        // 创建servlet
        tomcatServer.addServlet(CONTEXTPATH, "IndexServet", new IndexServet());
        // 添加servleturl映射
        standardContext.addServletMappingDecoded("/index", "IndexServet");
        tomcatServer.start();
        System.out.println("tomcat启动...");
        tomcatServer.getServer().await();
    }

}

启动程序,浏览器访问:http://127.0.0.1:8080/snow/index
在这里插入图片描述

3 SpringMVC(无配置启动)

3.1 SpringMVC 原理回顾

在这里插入图片描述

⑴ 用户发送请求至前端控制器 DispatcherServlet
DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
⑶ 处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet
DispatcherServlet 通过 HandlerAdapter 处理器适配器调用处理器
⑸ 执行处理器(Controller,也叫后端控制器)。
Controller 执行完成返回 ModelAndView
HandlerAdaptercontroller 执行结果 ModelAndView 返回给 DispatcherServlet
DispatcherServletModelAndView 传给 ViewReslover 视图解析器
ViewReslover 解析后返回具体 View
DispatcherServletView 进行渲染视图(即将模型数据填充至视图中)。
DispatcherServlet 响应用户。

3.2 SpringMVC 注解启动方式

DispatcherServlet 是 Spring MVC 的核心,每当应用接受一个 HTTP 请求,由 DispatcherServlet 负责将请求分发给应用的其他组件。

在旧版本中,DispatcherServlet 之类的 servlet 一般在 web.xml 文件中配置,该文件一般会打包进最后的 war 包中;但是 Spring 3 引入了注解,我们这节课讲解,如何基于注解配置 Spring MVC。

3.3 Maven 依赖

<dependencies>
    <!--Java语言操作tomcat -->
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>8.5.16</version>
    </dependency>
    <!-- spring-web -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.0.4.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <!-- spring-mvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.4.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <!-- tomcat对jsp支持 -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jasper</artifactId>
        <version>8.5.16</version>
    </dependency>
</dependencies>

3.4 加载 SpringMVCDispatcherServlet

AbstractAnnotationConfigDispatcherServletInitializer 这个类负责配置 DispatcherServlet、初始化 Spring MVC 容器和 Spring 容器。

getRootConfigClasses() 方法用于获取 Spring 应用容器的配置文件,这里我们给定预先定义的 RootConfig.classgetServletConfigClasses 负责获取 Spring MVC 应用容器,这里传入预先定义好的 WebConfig.classgetServletMappings() 方法负责指定需要由 DispatcherServlet 映射的路径,这里给定的是 "/",意思是由 DispatcherServlet 处理所有向该应用发起的请求。

package com.snow.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * 加载SpringMVCDispatcherServlet
 *
 */
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    // 加载根容器
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[] { RootConfig.class };
    }

    // 加载SpringMVC容器
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] { WebConfig.class };
    }

    // SpringMVCDispatcherServlet 拦截的请求 /
    protected String[] getServletMappings() {

        return new String[] { "/" };
    }

}

3.5 加载 SpringMVC 容器

正如可以通过多种方式配置 DispatcherServlet 一样,也可以通过多种方式启动 Spring MVC 特性。原来我们一般在 xml 文件中使用 <mvc:annotation-driven> 元素启动注解驱动的 Spring MVC 特性。

package com.snow.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * SpringMVC容器<br>
 *
 * @EnableWebMvc 开启SpringMVC功能<br>
 */
@Configuration
@EnableWebMvc
@ComponentScan("com.snow.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

}

3.6 RootConfig 容器

package com.snow.config;

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

/**
 * 根容器 <br>
 *
 */
@Configuration
@ComponentScan(basePackages = "com.snow")
public class RootConfig {

}

3.7 项目添加业务逻辑层

创建 Service 层

package com.snow.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public String index() {
        return "这是 UserService!";
    }

}

创建 Controller 层

package com.snow.controller;

import com.snow.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/index", produces = "text/html;charset=UTF-8")
    public String index() {
        return userService.index();
    }
}

3.8 启动类

package com.snow;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.StandardRoot;

import javax.servlet.ServletException;
import java.io.File;

public class TomcatApp {

    public static void main(String[] args) throws ServletException, LifecycleException {
        start();
    }

    public static void start() throws ServletException, LifecycleException {

        // 创建Tomcat容器
        Tomcat tomcatServer = new Tomcat();
        // 端口号设置
        tomcatServer.setPort(8080);
        // 读取项目路径
        StandardContext ctx = (StandardContext) tomcatServer.addWebapp("/", new File("src/main").getAbsolutePath());
        // 禁止重新载入
        ctx.setReloadable(false);
        // class文件读取地址
        File additionWebInfClasses = new File("target/classes");
        // 创建WebRoot
        WebResourceRoot resources = new StandardRoot(ctx);
        // tomcat内部读取Class执行
        resources.addPreResources(
                new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));
        tomcatServer.start();
        // 异步等待请求执行
        tomcatServer.getServer().await();

    }
}

测试:
在这里插入图片描述

3.9 对 JSP 页面支持

修改 WebConfig 创建视图解析器

package com.snow.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * SpringMVC容器<br>
 *
 * @EnableWebMvc 开启SpringMVC功能<br>
 */
@Configuration
@EnableWebMvc
@ComponentScan("com.snow.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

    // 创建SpringMVC视图解析器
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        //可以在JSP页面中通过${}访问beans
        viewResolver.setExposeContextBeansAsAttributes(true);
        return viewResolver;
    }

}

新增控制器层

package com.snow.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {

    @RequestMapping("/pageIndex")
    public String pageIndex() {
        return "pageIndex";
    }

}

在这里插入图片描述

测试:
在这里插入图片描述

发布了675 篇原创文章 · 获赞 214 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_42112635/article/details/104879675
今日推荐