序言
本文用于记载本人从零开始学习SpringBoot框架的从小白到会使用再到了解SpringBoot内部的工作原理。
作为学习笔记,会按照SpringBoot创建到使用原理深入的一个学习流程进行记录,在其中产生的注意点以及防坑指南应该会在评论中一一补充。若存在中间件的使用一般会以番外的形式稍稍提及一下,并不会深入,深入的学习的话,会单独启动一个系列的吧,也许......
再来说一下为什么要学习SpringBoot。首先,本人从来不在乎什么框架流行,只在乎该框架是否满足我当前的需求,并不会盲目的去追逐流行趋势,这也是为什么到现在SpringBoot流行这么久了才开始学习。而为什么SpringBoot会流行起来,一个主要的原因是它的高集成性,你只需要用注解,配置文件就能完成大部分的依赖注入和控制反转(在Spring本体中,以XML形式进行申明),能保证代码的简洁,不繁杂,而且敲击干净,不会因为配置过于复杂而导致你想修改一个配置,找都找不到诸如此类。这个是优点,同样也是缺点,因为我学习还不是很深入,发现了并没有配置的教程,只知道我该往配置文件里塞什么,从官网的配置教程抄一份下来,然后就没有然后了。遇到问题的时候我完全不知道该去那个类去找问题,是否是自己配置有问题还是说在使用的时候有问题。所以,综上所述SpringBoot既有优点,但也不是没缺点,但是高度集成省去了很多麻烦,是一个值得去学习的框架。
第一步、创建一个Maven工程或上Spring官网构建一个工程
1.进入到Spring官网创建工程或者进入该地址"https://start.spring.io/"构建自己的工程
2.使用开发工具创建maven工程
- 首先创建一个maven工程(不截图了,因为开发工具不一样会有不一样的效果)
- 再者,导入我们的核心SpringBoot依赖
顺便附上以父工程申明的图
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
- 创建Main方法
package com.sunfintech.zero.starter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {"com.sunfintech.*.**"})
public class SpringBootStarter {
public static void main(String[] args) {
SpringApplication.run(SpringBootStarter.class, args);
}
}
- 编写一个web层接口,并且使用Rest进行调用
package com.sunfintech.zero.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
//@Controller
@RequestMapping(value = "test")
public class SringBootController {
@GetMapping(value = "/hello")
// @RequestMapping(value = "/hello", method = RequestMethod.POST)
public Map<String, Object> testHelloWorld(){
System.out.println("Hello World");
Map<String, Object> map = new HashMap<String, Object>(16);
map.put("word", "Hello World");
return map;
}
}
以上就是创建SpringBoot的操作,手动创建说实话麻烦,而且容易出错,建议还是网上下载一份
启动一个SpringBoot工程
刚刚现在得到的SpringBoot工程运行前需要注意几件事
- 首先,注意一下包的扫描位置,SpringBoot扫描包的位置是默认选择当前目录的下级目录,例如:org.springframework.zero.starter下有一个SpringBoot的main方法,那么这个main方法就只会扫描org.springframework.zero.starter下的相关的被声明但没被排除的类
- 但是总会有人不喜欢在自己目录下(比如我就是),所以可以在@SpringBootApplication注解中加入相关的参数,比如scanBasePackages去指定包的扫描位置,同样,这玩意支持正则
- SpringBoot启动会依赖Resource源文件夹中application.properties(也可以是.yml)配置文件。这个是加载相关的配置选项的一个集中配置点,类似于Spring的applicationContext.xml
启动成功后回事这样样子
启动成功了,我们来访问一下接口试一下,因为是默认配置,所以我们使用PostMan发送一个请求http://127.0.0.1:8080/test/hello
注意:Spring的老用户们,这地方没去处理视图渲染,所以不要加什么.do呀的后缀
请求成功了,恭喜你,获得成就Hello World
创建一个SpringBoot的单元测试
单元测试是我们在写任何逻辑代码时都要做的一个测试,测试单个模块是否能用,逻辑是否正确,一个非常好用的东西
我们先创建一些需要测试的业务代码
首先是接口:
package com.sunfintech.zero.service;
public interface SpringBootService {
void testHelloWorld();
}
再次是实现类:
package com.sunfintech.zero.service.impl;
import org.springframework.stereotype.Service;
import com.sunfintech.zero.service.SpringBootService;
@Service("springBootService")
public class SpringBootServiceImpl implements SpringBootService{
@Override
public void testHelloWorld() {
System.out.println("HelloWorld");
}
}
最后是我们主角测试单元:
package com.sunfintech.zero.service.impl;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.sunfintech.zero.service.SpringBootService;
import com.sunfintech.zero.starter.SpringBootStarter;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootStarter.class)
class SpringBootServiceImplTest {
@Autowired
private SpringBootService springBootService;
@Test
void test() {
springBootService.testHelloWorld();
}
}
好了,坑点来了,对于初学者来说,你更本不知道要加上启动器这玩意,生成的测试单元以为这样就能用,就算是用过Spring的老手上来就算会加上,你不到他读取的配置文件时根据你jar文件里的来的,而不是当前配置文件,因为SpringBoot在Maven插件里没设置Resource读取的一个配置,要你自己去配置,这样子会对Eclipse用户超级不友好。所以SpringBoot开发推荐大家使用idea测试。
单元有两种操作,一种是像上图一样,标注一下我们的启动入口,还有一种是像下图这种操作。第二种方法就比较直接,毕竟SpringBoot包含Spring,所以使用Spring进行启动也是可以的
package com.sunfintech.zero.service.impl;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.sunfintech.zero.service.SpringBootService;
@RunWith(SpringRunner.class)
class SpringBootServiceImplTest {
@Test
@SuppressWarnings("resource")
public void contextloads() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext();
SpringBootService springBootService = applicationContext.getBean(SpringBootServiceImpl.class);
springBootService.testHelloWorld();
}
}
结语
虽然接触SpringBoot时间不长,但是作为集成度较高的框架,感觉上新手直接学习SpringBoot更好,先学习Spring如果手段不是好的话,会留下很多陋习(比如无脑抄配置),毕竟Spring本身比较开放,而且配置集中,对新手超级不友好。反观SpringBoot,配置简单,上手容易,省去很多麻烦事,对学习进阶帮助很大。所以我觉得大致的学习是SpringBoot->Spring->SpringBoot,最后反过来在学习SpringBoot主要是为了学习启动器的相关的配置为什么这么干的一个高级进阶。
最后,感谢所有的读者看我在这破事水,祝大家工作顺利。