目录
前言
SpringBoot
快速入门Springboot
Springboot做了啥(springboot源码跟踪)
热部署
YML规范
Junit Test的使用
带着问题学java系列博文之java基础篇。从问题出发,学习java知识。
之前我们使用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框架应运而出,并迅速“一统天下”。
Intellij IDEA很好的支持SpringBoot系列,推荐使用它进行后台开发,下面也以此举例,进行快速入门:
新建工程时选择“Spring Initializr”:
然后选择需要的依赖:可以看到工具自带了很多框架,我们只需要勾选就可以了。
一路next完成创建之后,可以看到工程结构如下:(controller是手动创建的)
打开pom.xml,可以看到自动为我们引入了相关依赖,并且勾选的框架也自动引入了。手动添加一个controller:
然后就可以直接运行我们的项目了,日志打印:
浏览器发起访问:
一个后台服务就完成,是不是非常简单。
上例快速入门SpringBoot,首先项目中没有最基础的两个配置文件web.xml和springmvc.xml,我们没有做任何配置。其次我们并没有安装tomcat,也没有部署的动作。但是整个服务却可以正常运行,而且从pom.xml可以看到,项目其实打包成了一个jar包。让我们简单跟踪一下springboot的源码,看看springboot到底做了啥,为什么可以如此简单的实现后台服务?
首先看下依赖:
自动为我们引入了一个父级依赖spring-boot-stater-parent,进入这个依赖:
可以看到它会自动加载resources文件夹下的application*.yml、application*.yaml和application*.properties,加载顺序如配置顺序,当存在多个匹配文件时,后面的覆盖前面的。然后spring-boot-starter-parent又有自己的父级依赖spring-boot-dependencies:
可以看到在这个父级依赖中,对好多的框架依赖进行了版本控制,这也是为什么自动导入的依赖,都没有版本号的原因。使用springboot,我们只需要关注springboot的版本,其他的框架依赖版本都交给springboot,这样我们就不用再担心各个框架之间由于版本不匹配,而导致的功能异常,或者依赖冲突问题等(小贴士:springboot中预先配置好了常见框架的版本,但是有时候也可能存在我们想用的框架不在其中,这时候就需要我们手动配置版本。一般我们用到的框架springboot都已经配置了,如果出现没有配置的,建议尝试百度是不是自己想用的框架过于冷门,或者springboot中配置了更好的替代框架)。
再跟踪一下我们勾选的依赖spring-boot-starter-web:
可以看到这个依赖包含了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工程入口:
看下这个@SpringBootApplication注解做了啥:
一路跟踪,可以看到这个注解自动加载了一份在AutoConfigurationImportSelector.java所在工程的META-INF/spring.factories,作为整个服务的基础bean配置。
打开spring.factories,搜索一下servlet,可以看到:
原来我们之前在web.xml中配置的dispatcherServlet,springboot框架在这里为我们进行了自动配置,所以不需要web.xml中配置了。
在AutoConfigurationImportSelector.java所在工程的中还有一份json,spring-configuration-metadata.json,打开看下,搜索server.port:
可以看到原来在这里配置了默认值,这也就是为什么直接启动服务的时候,端口是8080了。
使用springboot之后,在开发过程中有一个小功能可以使用——热部署。热部署就是服务启动后,我们进行了代码修改,此时不需要重新打包启动服务,就可以热加载,修改的地方自动生效了。下面演示一下范例:
1.引入热部署依赖:
org.springframework.boot
spring-boot-devtools
runtime
true
2.开启IDEA的自动编译(否则热部署将不会生效)
ctrl+shift+alt+/,进入registry:
至此热部署功能已开启,可以测试一下:
@RestController
@RequestMapping("/first")
public class FirstController {
@RequestMapping("/hot")
public String testHotDeploy(){
return "nihao world!";
}
}
启动服务,浏览器访问 /first/hot,打印“nihao world!”,修改一下,改为“Hello world!”,再次发起访问,可以看到打印的是“Hello world!”,修改实时生效了。热部署主要用于开发过程中,便于我们进行开发调试。
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
在开发过程中,有时候我们想对某一个模块进行单独测试,之前我们没有很好的方法,只有完成整个功能开发,然后启动服务,发起请求进行测试。这样很不方便,拿数据库操作举例,我们想测试一下某个方法是否可以如期望执行,此时就需要我们完成整个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层功能测试。
以上系个人理解,如果存在错误,欢迎大家指正。原创不易,转载请注明出处!