Spring Boot实战:逐行释义HelloWorld

1、前言java

   研究Spring boot也有一小段时间了,最近会将研究东西整理一下给你们分享,大概会有10~20篇左右的博客,整个系列会以一个简单的博客系统做为基础,由于光讲理论不少东西不是特别容易理解,而且若是每次经过一个简单的小程序也没法系统的把握好一些知识点,因此就以一个简单的系统做为基础来说,看看经过spring boot如何实现一个完整系统。本系列除了Spring boot基本的知识点以外,还会涉及到Spring boot与数据库、缓存(redis)、消息队列等的结合以及多实例部署等方面的内容。有兴趣的同窗能够关注一下。web

2、Spring boot 简介redis

   Spring boot 从名称上就能够看出,它是基于Spring的一个框架,因此不熟悉Spring的同窗仍是得先去学习一下Spring。其次,Spring boot帮咱们集成不少经常使用的功能,使得整个配置更加简单。用过Spring的同窗应该知道,虽然Spring一直在努力的减小配置的复杂性,可是,配置一个彻底可用的(web)环境仍是挺麻烦的,好比须要配置日志、数据库、缓存等,而后再配置tomcat,最后将程序发布到tomcat目录下。而Spring boot则帮咱们大大简化了这个过程,它提供了不少starter,只要引入对应的jar包就能够了。例如,咱们须要集成tomcat,只须要引入tomcat的starter便可:spring

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>

  备注:本文的例子都是基于Maven来实现的,因此若是不熟悉Maven,能够先去看下怎么用,若是熟悉gradle的话,也能够根据状况对配置作相应调整。数据库

  咱们能够从官方文档上查看Spring boot提供的starter:json

  这里我只截取了一小部分,能够看到Spring boot支持缓存、批处理、mq、es等等,完整的列表参考官方文档。其余就很少解释了,后续经过示例来说解整个Spring boot功能,咱们先看Spring boot来如何实现一个web版的Hello World!小程序

3、Hello World程序缓存

  3.1 Hello World 源码tomcat

  第一步:导入jar包架构

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

  第二步:编写控制器类  

package com.pandy.blog;

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

import java.util.HashMap;
import java.util.Map;

@Controller
public class HelloWorld {
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String, Object> hello() {
        Map<String, Object> map = new HashMap<>();
        map.put("hello", "world");
        return map;
    }
}

  第三步:编写启动类(入库)

package com.pandy.blog;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

 运行该类的main方法,而后访问http://localhost:8080/hello,就能够看到以下结果:

  是否是感受很开心?一行配置都没有,就能够直接运行一个Web应用。不过开心完之后有没有想过这是怎么实现的呢?接下来咱们一行一行解析上面的代码,虽然行数很少,可是仍是有不少东西值得咱们去学习和理解的。

  3.2 pom文件分析

  咱们先从pom文件入手,pom文件里面只引入了两个依赖项。第一个是spring-boot-starter-parent,熟悉Maven的朋友应该知道,Maven也能够跟类同样,从父pom文件中继承配置。咱们能够看下spring-boot-starter-parent的pom文件,因为篇幅问题,这里面只看两部分,其余东西比较容易理解,你们能够本身读一下。第一个部分是:

  该文件又继承了另外一个pom文件,即spring-boot-dependencies,这个文件其实就是包含了一大堆的jar,其做用是统一管理spring boot所依赖的jar包的版本,因此以后你们能够看到,各个组件里面引入jar的时候就再也不须要再指定版本号了。另外一个地方须要说明一下是配置文件的管理:

  你们能够看到,默认状况下会将/src/main/resources目录下的文件做为资源文件加入到classpath下,另外,这个地方的仅仅对application*.yml,application*.yaml,application*.properties三种文件进行过滤。这个过滤是指什么呢?你们配置过spring mvc的人应该都知道,配置数据库时,咱们一般将数据库的信息配置在一个properties文件中,而后在spring的配置文件中经过<property name="driverClass" value="${jdbc.driver}" /> 的形式引入,这个filter的做用就是在编译的时候将配置文件中配置的名值对替换到spring的配置文件中${xxx}字符,但这个功能不是必要的,即便不进行替换,Spring也能在运行时读取到配置项。

  总结一下:spring-boot-starter-parent的做用::

  1)jar包的版本管理。

  2)配置文件的过滤。

  3)经常使用插件管理。

  spring-boot-starter-parent最核心的功能是管理了Spring boot所依赖的全部jar包。不过通parent的方式有一个很明显的问题,不少公司本身有本身的parent文件,而maven是没办法配置多个parent的。若是不使用spring-boot-starter-parent,那应该怎么作??实际上Spring boot提供了另外一种方式来解决这个问题,就是在本身的pom文件中加入spring boot的依赖的管理:

<dependencyManagement>
     <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.9.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

  其实从上面的分析能够看到,这个也是spring-boot-starter-parent 的pom文件的parent,而这个pom文件里面主要就是管理了一大堆的jar包版本。因此导入这个后,就不须要本身再去作版本管理,各个starter会本身根据须要导入对应的jar,但版本号由spring-boot-dependencies统一管理。可是这样的话,spring-boot-starter-parent中的插件就没法使用,而且默认配置文件的过滤功能也没有了。不过这没什么影响,一方面这些功能不是必须的,另外一方面若是须要,本身添加也是件很容易的事情。  

  3.3 HelloWorld类解析:

  咱们再看下HelloWorld这个类,用过Spring mvc应该知道,其实这个类跟Spring boot没半毛钱关系,业务代码更是没任何跟spring相关的东西,这也是spring一直奉行的一个原则,侵入性极小,这也是Spring成功的一个主要缘由。这个类里面跟spring相关的是三个注解,即@Controller,@RequestMapping,@ResponseBody,可是这三个注解也都是Spring mvc提供的。跟Spring boot没有太多联系,在这我就不细讲了,若是不是很清楚,能够去看下Spring MVC的内容,三个注解的基本做用以下:

  • Controller:标识为一个控制器,spring会自动实例化该类。
  • RequestMapping:url映射。
  • ResponseBody:将返回结果自动转换为json串。

  3.4 Application类解析

  最后咱们看下Application这个类,你会发现这个类的东西更少,总共就一行有用的代码,即SpringApplication.run(Application.class, args);这个方法的做用是加载Application这个类,那Application这个类有什么特别之处吗?能够看一下,其实这个类的惟一特殊的地方是一个注解@SpringBootApplication,因此Spring boot的运行确定跟这个注解有着诸多的联系,咱们能够看下这个注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  该注解的主要方法就不说了,你们看下就知道,主要是为上面这些注解提供别名。该注解上前四个注解(@Target(ElementType.TYPE),@Retention(RetentionPolicy.RUNTIME),@Documented,@Inherited)你们应该都知道,不熟悉的朋友本身去看下JDK如何实现自定义的注解。咱们详细解释一下后面三个注解:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。

  先看一下SpringBootConfiguration,这个注解比较简单,源码以下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

  这个注解仅仅是继承了@Configuration,你们应该知道,Spring提供三种方式的配置:(1)xml文件配置(2)annotation配置(3)Java 类配置。而@Configuration就是用于标识一个类为配置类的注解。Spring 4之后比较推崇经过Java类的方式来进行配置,因此Spring boot也倾向于这种方配置式。而且从源码能够看出,SpringBootConfiguration的做用就是标识类为配置类。

  接下来咱们看一下@EnableAutoConfiguration注解,这个注解的源码有点复杂,在这不作细讲,后面的文章再详细解析期实现方式。这里说一下该注解的做用,它的主要功能是实现自动配置,什么叫作自动配置?就是Spring boot会根据你引入的jar包作一些自动的配置,例如,在classpath有HSQLDB的jar,spring boot就会自动给你配置一个内存数据库。在这个例子里面咱们也能够看到,由于咱们引入了Spring-mvc、tomcat等相关的jar,spring boot就会猜想你是一个web工程,而后就会自动作一些spring mvc的配置,好比对静态资源的支持、将返回结果自动转为json格式数据的支持等。这些都是自动配置的结果。对Spring Enable*注解熟悉的同窗应该可以更容易理解这个注解,由于Spring中有不少相似的注解。

  最后咱们再看下@ComponentScan,这个注解不是Spring boot提供的,而是Spring提供的,Spring扫描的包或类,即哪些包和类会自动归入Spring IoC容器的管理,IoC根据配置对这些类进行实例化。

   如今咱们再总结一下SpringBootConfiguration这个注解的做用:

  1)标志该类为一个配置类。
  2)指定扫描的包,便于Spring IoC容器对其进行实例和生命周期的管理。
  3)自动配置,经过引入的jar包,猜想用户的意图进行自动化配置。

4、总结

   本文详细分析了Spring boot实现的一个web版的Hello World,经过这个例子,咱们了解了Spring boot的基本操做,并经过对每行的代码的分析,对Spring boot的原理有了一个大体的了解。整体来说,Spring boot 统一管理了jar包,而后会根据咱们选择的starter来进行自动化配置,经过这种方式来解决复杂的依赖管理,精简配置,从而使得开发者可以更加专一于本身的业务,而不须要作那些很复杂的配置工做。同时,Spring boot这种快速、轻量级的服务也很是适合微服务架构,这个后续有机会再跟你们分享,欢迎继续关注。

相关文章
相关标签/搜索