从本章开始,我将一步步地带领读者学习Spring Boot到Spring Cloud的基础知识,并在此基础上,完成实际项目的开发。

Spring Boot简介

Spring Boot是由 Pivotal团队提供的基于Spring的全新框架,其设计目的是简化Spring应用的搭建和开发过程。该框架遵循“约定大于配置”原则,采用特定的方式进行配置,从而使开发者无须进行大量的XML配置。Spring Boot致力于成为蓬勃发展的快速应用开发领域的领导者。

Spring Boot并不重复“造轮子”,而是在原有Spring框架的基础上进行封装,并且它集成了一些类库,用于简化开发。换句话说,Spring Boot就是一个大容器。

关于 Spring Boot,其官网是这样描述的:

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.

从上面的描述中,我们可以了解到,Spring Boot带给了我们全新的应用部署方案,通过它可以很方便地创建独立的、生产级的基于Spring的应用程序。同时,通过 Spring平台和第三方库可以轻松创建视图。

其实,Spring Boot默认集成了 Tomcat,因此我们可以只编译成jar包,通过 Java命令启动应用, 大多数Spring Boot应用程序只需要很少的Spring配置。

你好!世界

我们学习任何一门语言、一种框架,第一件事就是编写"Hello,World"程序,本专题也不例外,本节,我们就来编写入门Spring Boot的第一个程序。

打开IDEA,依次点击File->New->Project,如图1-1所示。

Springboot 在信创环境下可以用吗_配置文件


图1-1 IDEA项目创建图

然后选择Maven,并点击下一步,如图1-2所示。

Springboot 在信创环境下可以用吗_配置文件_02


图1-2 IDEA项目创建图

在GroupId后输入com.lynn.demo,ArtifactId后输入demo,依次点击Next->Finish,即可创建好一个空的Maven工程,如图1-3所示。

Springboot 在信创环境下可以用吗_spring_03


图1-3 项目示例图

接下来,我们就来编写第一Spring Boot应用。

首先,在pom.xml中加入Spring Boot相关依赖。

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>
    </dependencies>

由于Spring Boot基于Spring MVC,它是一个Web工程,因此我们需要依赖spring-boot-starter-web,使其集成Spring MVC,否则工程无法正确启动;在导读篇我已提到,为了简化代码,本专题的示例中均依赖lombok框架,因此在pom.xml中,也加入了该框架。

然后,编写应用的启动类,代码如下:

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

@SpringBootApplication
public class Application {

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

上述代码中,我们只编写了一个main方法,通过SpringBoot内置的SpringApplication来启动应用程序,这就是Spring Boot的强大之处,因为它集成了Tomcat容器,因此我们无需安装Tomcat即可启动它。

需要注意的是,启动类必须添加@SpringBootApplication注解,否则启动会报错,该注解表明Application类是SpringBoot启动类,而启动时的很多操作都是需要通过该注解完成的配置,读者通过查看SpringBootApplicaiton源码可明白一二。

@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 {

	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;
}

由于本专题为入门专题,故对Spring Boot源码不做详细分析。

最后,启动Application类,在控制台可以看到如图1-4所示信息。

Springboot 在信创环境下可以用吗_配置文件_04



这样,我们就完成了Spring Boot应用程序的启动。但是,上述代码无任何功能,本节最开始,我提到了要编写"Hello,Word"程序,我们需要在浏览器中显示出来。

Spring Boot已经集成了Spring MVC,因此我们接下来的操作和Spring MVC大同小异,编写一个Controller,并提供HTTP地址即可。代码如下:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("hello")
public class HelloController {

    @RequestMapping("index")
    public String index(){
        return "你好!世界!";
    }
}

然后重启Application,浏览器访问:http://localhost:8080/hello/index,可看到如图1-5所示界面。

Springboot 在信创环境下可以用吗_spring_05


图1-5 运行效果

配置文件

在上一节的示例中,读者可以发现,我们没有编写一个XML配置,甚至没有一个配置文件就可以启动一个Web应用程序。那是因为,Spring Boot对于每种配置都有自己的默认值。

例如:端口默认为8080,上下文路径默认为“/”。

整个Spring Boot应用程序,我们可以只需要一个配置文件即可,Spring Boot应用启动时,会将该配置文件内容加载到Spring容器中。Spring Boot支持两种格式的配置文件,它们分别是propertes和yml。Spring Boot官方默认properties格式的配置文件,但笔者认为,yml文件结构更加明了,可读性更好,因此笔者推荐读者也采用yml格式的配置文件。本专题的配置也全采用yml格式。

接下来,就跟随我一起来探究yml格式吧!

yml文件的基本格式如下:

key1:
	key2:
		key3: value
	key4:
		key5: value1

我们将它替换成properties格式,即key1.key2.key3=value和key1.key4.key5=value1。可以看到,yml的层次结构较为清晰。当然,key的个数不是固定的。这里需要说明的是,yml格式非常严格,如果当前的key后面需要跟value,则冒号后面必须至少有一个空格,否则启动会报错;其次,每个子属性之间需要通过空格或制表符(即按下Tab键)分隔,否则可能无法获取到正确的属性。

在后面的讲解中,如果代码形式,将采用yml格式展示,为了便于解释,如果代码解释则采用properties格式加以说明。

在src/main/resources下创建名为application.yml的文件,并编写下述代码:

server:
  port: 8081
  servlet:
    context-path: /api

上述代码中,server.port表示应用端口,本示例改为8081,server.servlet.context-path为上下文路径,本示例改为/api。启动应用程序,访问http://localhost:8081/api/hello/index,可以看到图1-5相同的运行效果。

本节主要对yml格式进行一定的说明,并做了简单的效果展示,在后面的学习中,Spring Boot应用的大部分配置说明都将一一呈现。

配置类

不知道读者是否还有印象,在Spring MVC中,我们定义一个Bean或者一个Component都是在XML里面设置,譬如下述代码:

<bean class="com.lynn.demo.Bean">
	<property value="id">1</property>
	<property value="name">2</property>
</bean>

Spring Boot定义一个Bean,就非常简单,只需要一个注解就行。

首先创建一个普通类Person,编写下述代码:

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

@Data
@Builder
@ToString
public class Person {

    private Long id;

    private String name;
}

然后编写配置类,我们取名为WebConfig,并编写下述代码:

@SpringBootConfiguration
public class WebConfig{


    @Bean
    public Person person(){
        return Person.builder().id(1L).name("lynn").build();
    }
}

上述代码中,我们首先添加@SpringBootConfiguration注解,凡是添加了该注解的类都可以是SpringMVC的配置类,都可以在里面定义Bean;然后,将Person实例化并初始化一些值,并添加@Bean注解,应用启动时,Spring就可以将Person类加入到Spring容器中,我们就可以在任何Spring的容器类中注入他。

本节暂不做演示,在后面读者将看到Person类的输出。

自定义Json转换器

我们在Controller输出结果时,Spring Boot默认用Jackjson框架解析结果并返回,如果读者不喜欢该框架,Spring Boot也支持改变Json转换器,下面以Fastjson为例,来演示如何改变为Fastjson。

首先修改WebConfig类,使其继承WebMvcConfigurationSupport类,并重写configureMessageConverters,添加代码如下:

@SpringBootConfiguration
public class WebConfig extends WebMvcConfigurationSupport {
	@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig=new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat
        );
        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        fastConverter.setSupportedMediaTypes(mediaTypeList);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastConverter);
    }
}

重启Application,浏览器访问应用,可以看到图1-6所示界面。

Springboot 在信创环境下可以用吗_配置文件_06


图1-6 运行效果

读者可以发现,返回的界面样式和图1-5有所区别,说明Json转换器改变成功了。

拦截器

在一个大型应用中,会涉及到许多安全性要求较高的接口,因此需要一些安全策略来保证接口传输的安全性。我们在编写代码时,不可能对所有接口都写一遍安全性校验,这时就需要用到拦截器了。

拦截器会将所有HTTP请求地址进行拦截,我们可以在拦截器里做相应的安全性处理,如果合法请求则通过,否则拦截。

Spring Boot创建拦截器很简单。首先创建名为ApiInterceptor的类,并实现HandlerInterceptor接口,并编写下述代码:

@Slf4j
public class ApiInterceptor implements HandlerInterceptor {

    @Autowired
    private Person person;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("调用接口前" + person);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        log.info("调用接口时");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        log.info("调用接口后");
    }
}

上述代码中,我们注入了前面编写的Person类,并在拦截器里打印出来。该拦截器共有三个方法,其中,preHandle为接口调用前执行,postHandle为接口调用时执行,afterCompletion为接口调用完成后执行。我们进行安全策略一般在preHandle方法编写,该方法返回boolean值,为false则被拦截,即不会再调用指定的接口了,为true则允许继续调用指定接口。

我们启动Application类,并访问HTTP地址,控制台可以看到图1-7所示信息。

Springboot 在信创环境下可以用吗_配置文件_07


图1-7 IDEA控制台日志