Java EE--框架篇(4)SpringBoot

目录

前言

SpringBoot

快速入门Springboot

Springboot做了啥(springboot源码跟踪)

热部署

YML规范

Junit Test的使用


前言

带着问题学java系列博文之java基础篇。从问题出发,学习java知识。


SpringBoot

之前我们使用SSH(Spring SpringMVC Hibernate)开发后台应用,底层都是Java EE规范,其根本都是Servlet、Filter和Listener;然后就是配置文件,首先有一个必须的web.xml,它是配置servlet、filter等(比如dispatcherServlet和characterEncodingFilter),目的是让web容器识别到整个后台服务的servlet和filter等,并初始化反射创建servlet和filter实例;还有一个是springmvc.xml,它是配置spring框架的配置文件,主要用于配置spring相关功能(比如开启注解扫描,指定扫描的包路径(扫描controller、service、intercept等),配置视图解析器等),另外它还是集成其他框架的主要配置文件,在这里进行spring整合其他框架(比如,使用bean标签配置mybatis,开启事务等)。服务写好之后,需要打包成war,部署到web容器中(比如Tomcat),依赖容器运行。

整个流程下来,其实还是很繁琐的,即使是全注解框架,我们还是逃避不了两个基础的配置文件web.xml和springmvc.xml。运行依赖的容器必须预先安装调试,确保版本支持后台服务的相关功能,然后还要进行war部署;如果涉及容器性能上的调优,那还得找到容器(比如tomcat的config)的配置文件,进行对应的参数优化。为了更加简化整个后台服务的基础开发工作,SpringBoot框架应运而出,并迅速“一统天下”。

 

快速入门Springboot

Intellij IDEA很好的支持SpringBoot系列,推荐使用它进行后台开发,下面也以此举例,进行快速入门:

新建工程时选择“Spring Initializr”:

Java EE--框架篇(4)SpringBoot_第1张图片

然后选择需要的依赖:可以看到工具自带了很多框架,我们只需要勾选就可以了。

Java EE--框架篇(4)SpringBoot_第2张图片

一路next完成创建之后,可以看到工程结构如下:(controller是手动创建的)

Java EE--框架篇(4)SpringBoot_第3张图片

打开pom.xml,可以看到自动为我们引入了相关依赖,并且勾选的框架也自动引入了。手动添加一个controller:

Java EE--框架篇(4)SpringBoot_第4张图片

然后就可以直接运行我们的项目了,日志打印:

Java EE--框架篇(4)SpringBoot_第5张图片

浏览器发起访问:

Java EE--框架篇(4)SpringBoot_第6张图片

一个后台服务就完成,是不是非常简单。

 

Springboot做了啥(springboot源码跟踪)

上例快速入门SpringBoot,首先项目中没有最基础的两个配置文件web.xml和springmvc.xml,我们没有做任何配置。其次我们并没有安装tomcat,也没有部署的动作。但是整个服务却可以正常运行,而且从pom.xml可以看到,项目其实打包成了一个jar包。让我们简单跟踪一下springboot的源码,看看springboot到底做了啥,为什么可以如此简单的实现后台服务?

首先看下依赖:

Java EE--框架篇(4)SpringBoot_第7张图片

自动为我们引入了一个父级依赖spring-boot-stater-parent,进入这个依赖:

Java EE--框架篇(4)SpringBoot_第8张图片

可以看到它会自动加载resources文件夹下的application*.yml、application*.yaml和application*.properties,加载顺序如配置顺序,当存在多个匹配文件时,后面的覆盖前面的。然后spring-boot-starter-parent又有自己的父级依赖spring-boot-dependencies:

Java EE--框架篇(4)SpringBoot_第9张图片

可以看到在这个父级依赖中,对好多的框架依赖进行了版本控制,这也是为什么自动导入的依赖,都没有版本号的原因。使用springboot,我们只需要关注springboot的版本,其他的框架依赖版本都交给springboot,这样我们就不用再担心各个框架之间由于版本不匹配,而导致的功能异常,或者依赖冲突问题等(小贴士:springboot中预先配置好了常见框架的版本,但是有时候也可能存在我们想用的框架不在其中,这时候就需要我们手动配置版本。一般我们用到的框架springboot都已经配置了,如果出现没有配置的,建议尝试百度是不是自己想用的框架过于冷门,或者springboot中配置了更好的替代框架)。

再跟踪一下我们勾选的依赖spring-boot-starter-web:

Java EE--框架篇(4)SpringBoot_第10张图片

可以看到这个依赖包含了tomcat的相关依赖、spring-web和spring-webmvc的相关依赖。这也就是为什么我们不需要再部署服务到tomcat,就可以直接运行了。是因为springboot将tomcat核心jar引入了工程,并在打包的时候一并打包,因此直接运行后台服务jar就可以了。它的本质其实还是部署在tomcat中运行,只是tomcat的安装、服务war的部署等工作都被springboot替我们干了。从运行日志也可以看到:springboot 2.4.0为我们自动引入的是9.0.39版本的tomcat,tomcat的启动端口是8080.

再跟踪下代码,发现工具给我们自动生成了一个java类,而且还是java工程入口:

Java EE--框架篇(4)SpringBoot_第11张图片

看下这个@SpringBootApplication注解做了啥:
Java EE--框架篇(4)SpringBoot_第12张图片

一路跟踪,可以看到这个注解自动加载了一份在AutoConfigurationImportSelector.java所在工程的META-INF/spring.factories,作为整个服务的基础bean配置。

Java EE--框架篇(4)SpringBoot_第13张图片

打开spring.factories,搜索一下servlet,可以看到:

Java EE--框架篇(4)SpringBoot_第14张图片

原来我们之前在web.xml中配置的dispatcherServlet,springboot框架在这里为我们进行了自动配置,所以不需要web.xml中配置了。

在AutoConfigurationImportSelector.java所在工程的中还有一份json,spring-configuration-metadata.json,打开看下,搜索server.port:

Java EE--框架篇(4)SpringBoot_第15张图片

可以看到原来在这里配置了默认值,这也就是为什么直接启动服务的时候,端口是8080了。

 

热部署

使用springboot之后,在开发过程中有一个小功能可以使用——热部署。热部署就是服务启动后,我们进行了代码修改,此时不需要重新打包启动服务,就可以热加载,修改的地方自动生效了。下面演示一下范例:

1.引入热部署依赖:

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        

2.开启IDEA的自动编译(否则热部署将不会生效)

Java EE--框架篇(4)SpringBoot_第16张图片

ctrl+shift+alt+/,进入registry:

Java EE--框架篇(4)SpringBoot_第17张图片

至此热部署功能已开启,可以测试一下:

@RestController
@RequestMapping("/first")
public class FirstController {

    @RequestMapping("/hot")
    public String testHotDeploy(){
        return "nihao world!";
    }
}

启动服务,浏览器访问 /first/hot,打印“nihao world!”,修改一下,改为“Hello world!”,再次发起访问,可以看到打印的是“Hello world!”,修改实时生效了。热部署主要用于开发过程中,便于我们进行开发调试。

 

YML规范

springboot支持一种新的文件格式作为配置文件,也是官方推荐的配置文件格式yml或者yaml。YAML (YAML Ain't a Markup Language)YAML不是一种标记语言,通常以.yml为后缀的文件,是一种直观的能够被电脑识别的数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,一种专门用来写配置文件的语言。可用于如: Java,C/C++, Ruby, Python, Perl, C#, PHP等。

学习一下其数据配置:

#普通数据配置
name: 张三

#对象的配置
person:
  name: 李四
  age: 18
  address: 合肥

#行内对象配置
person1: {name: 张三, age: 18,address: 合肥}

#数组配置
city:
  - 北京
  - 重庆
  - 上海
  - 合肥

class:
  - student:
      name: lisi
      age: 18
  - student:
      name: zhangsan
      age: 19

#行内数组配置
city1: [北京,重庆,上海,合肥]
class1: [student:{name: lisi,age: 18},student:{name: zhangsan,age: 19}]

#Map配置
map:
  key: value
  key2: value2

代码中获取yml的值举例:

使用@value注解:

    @Value("${name}")
    private String name;

使用@ConfigurationProperties注解(注意这个注解要用在bean上面,否则spring框架将不会扫描,也就不会自动注入值了):

@Service
@ConfigurationProperties(prefix = "person")
public class GetDataService {

    private String name;
    private String address;
    private Integer age;
}

使用@ConfigurationProperties注解,相当于告诉spring框架,当前类注入值的前缀是person,注入的内容是person.name、person.address和person.age。当然也可以使用@Value注解,比如@Value("${person.name}")。

注意当使用了@ConfigurationProperties注解的时候,idea会报出一个警告,提示没有yml解释执行器,此时可以不管它,项目还是可以正常运行。如果想去掉,可以添加一个依赖

        
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

 

Junit Test的使用

在开发过程中,有时候我们想对某一个模块进行单独测试,之前我们没有很好的方法,只有完成整个功能开发,然后启动服务,发起请求进行测试。这样很不方便,拿数据库操作举例,我们想测试一下某个方法是否可以如期望执行,此时就需要我们完成整个controller api、service、dao三层的编写,然后发起请求,传入参数。用了springboot之后,就可以单独对dao层进行测试了。举例如下:

1.引入依赖

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

2.创建测试类

@SpringBootTest
@RunWith(SpringRunner.class)
public class PeopleRepositoryTest {

    @Autowired
    PeopleRepository peopleRepository;

    @Test
    @Transactional
    public void testCache(){
        Optional people = peopleRepository.findById(1);
        System.out.println(people.get());
    }
}

可以直接执行testCache()方法,进行dao层功能测试。


以上系个人理解,如果存在错误,欢迎大家指正。原创不易,转载请注明出处!

你可能感兴趣的:(spring,boot,容器,java)