032:SpringBoot大体流程源码分析

  • 1 SpringBoot快速开发底层实现原理
  • 2 SpringBoot去除XML,采用注解方式原理
  • 3 SpringBoot内置Tomcat服务器原理
  • 4 SpringBootStarter基本思想介绍
  • 5 SpringBoot自定义Starter插件01
  • 6 SpringBoot自定义Starter插件02


1 SpringBoot快速开发底层实现原理

课程内容:
1.SpringBoot底层设计原理与思想
2.如何自定义SpringBootStarter
3.模拟手写SpringBoot核心思想

SpringBoot核心理念:

  1. 能够实现帮助开发者快速整合第三方框架(Spring、Mybatis、Hibernate)
    原理:Maven依赖封装整合和自定义starter(springboot快速整合第三方框架依赖spring-boot-starter-xxx)。

2 SpringBoot去除XML,采用注解方式原理

  1. 完全去除xml配置,采用注解配置
    原理:SpringBoot其实根据Spring体系原生的注解实现包装。

@SpringBootApplication封装@Configuration目的,方便开发者在启动类中main函数下面写@Bean将第三方依赖注入到ioc容器中。

spring boot 3 无效的源发行版17 springboot源码解读与原理分析_java

3 SpringBoot内置Tomcat服务器原理

3.不需要外部容器,内嵌入服务器(tomcat)
原理:Java语言创建tomcat服务器,然后将本地class文件交给tomcat加载。

案例:注解方式启动SpringMVC将SpringMVC交给内部tomcat运行。
引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.4.RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>8.5.28</version>
    </dependency>
    <!-- Tomcat对jsp支持 -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jasper</artifactId>
        <version>8.5.16</version>
    </dependency>
</dependencies>

相关代码

@EnableWebMvc
@Configuration
@ComponentScan("com.mayikt.controller")
public class SpringMvcConfig {
}
@RestController
public class IndexController {
    //@RestController 等同于@Controller+@ResponseBody

    @RequestMapping("/")
    public String index() {
        return "mayikt";
    }
}
public class WebInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
        // 1.   创建SpringMVC容器
        AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
        // 2. 注册我们的配置文件
        app.register(SpringMvcConfig.class);
        // 注册我们的
        DispatcherServlet dispatcherServlet = new DispatcherServlet(app);
        ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcherServlet", dispatcherServlet);
        dynamic.addMapping("/");
        dynamic.setLoadOnStartup(1);// 最优先启动

    }
}
public class TomcatTest {
    public static void main(String[] args) throws LifecycleException, ServletException {
        //创建Tomcat服务器
        Tomcat tomcatServer = new Tomcat();
        //指定端口号
        tomcatServer.setPort(9090);
        //读取项目路径
        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, "/target/classes", additionWebInfClasses.getAbsolutePath(), "/"));
        tomcatServer.start();
        //异步等待请求执行
        tomcatServer.getServer().await();

    }
}

运行结果:

spring boot 3 无效的源发行版17 springboot源码解读与原理分析_java_02

4 SpringBootStarter基本思想介绍

Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境(条件)进行自动配置。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,Spring Boot就能自动扫描并加载相应的模块。
例如,在Maven的依赖中加入spring-boot-starter-web就能使项目支持Spring MVC,并且Spring Boot还为我们做了很多默认配置,无需再依赖spring-web、spring-webmvc等相关包及做相关配置就能够立即使用起来。
Starter其实就是SpringBoot对第三方常用框架组件的命名方式。
官方命名格式为: spring-boot-starter-{name}
非官方建议命名格式:{name}-spring-boot- starter

5 SpringBoot自定义Starter插件01

假设开发一个框架解决token幂等问题,支持springboot版本,需要配置redis连接

构建自定义starter插件:token-redis-spring-boot-starter
引入maven依赖

<!--  springboot-parent -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

<dependencies>
    <!-- Compile dependencies -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
    <!--  能够让我们编写的配置文件在 其他人引用的时候有一定提示-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
</dependencies>

相关代码

@ConfigurationProperties(prefix = "mayikt")
public class TokenProperties {

    private String tokenRedisHost;
    private String tokenRedisPwd;

    // mayikt.tokenRedisHost 写法错误
    // mayikt.tokenRedisPwd
    /*
    tokenRedisHost=token-redis-host
    mayikt.token-redis-host
     定义配置文件的key的时候没有大写 都是为小写
     */
    public void setTokenRedisHost(String tokenRedisHost) {
        this.tokenRedisHost = tokenRedisHost;
    }

    public void setTokenRedisPwd(String tokenRedisPwd) {
        this.tokenRedisPwd = tokenRedisPwd;
    }

    public String getTokenRedisHost() {
        return tokenRedisHost;
    }

    public String getTokenRedisPwd() {
        return tokenRedisPwd;
    }
}
@Configuration
@EnableConfigurationProperties(TokenProperties.class)
public class TokenAutoConfiguration {

    @Bean
    public TokenService tokenService(){
        return new TokenService();
    }
}
public class TokenService {
    @Autowired
    private TokenProperties tokenProperties;

    public String getToken() {
        System.out.println("模拟生成token");
        return tokenProperties.getTokenRedisHost() + "," + tokenProperties.getTokenRedisPwd();
    }
}

6 SpringBoot自定义Starter插件02

  1. 在resource目录下新建META-INF/spring.factories文件,内容:org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.mayikt.config.TokenAutoConfiguration(spring容器在启动的时候默认读取该文件内容)。
  2. 将该jar包打入maven仓库中,项目同级控制台输入命令: mvn clean install

新建项目test_springboot测试打入的jar包
引入maven依赖

<!--  springboot-parent -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.mayikt</groupId>
        <artifactId>token-redis-spring-boot-starter</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

application.yml

mayikt:
  token-redis-host: 127.0.0.1
  token-redis-pwd: 123456

启动测试类

@RestController
@SpringBootApplication
public class IndexController {

    @Autowired
    private TokenService tokenService;

    @RequestMapping(value = "/token")
    private String getToken(){
        return tokenService.getToken();
    }

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

}

测试结果:

spring boot 3 无效的源发行版17 springboot源码解读与原理分析_ci_03