SpringBoot程序开发
本小记学习目标
-
SpringBoot开发的标准过程
-
SpringBoot注解分析
-
SpringBoot的调试
-
SpringBoot内置对象
-
SpringBoot配置环境信息
-
SpringBoot项目中资源文件的读取
-
Spring配置的整合
-
SpringBoot的打包发布
-
profile配置
一、SpringBoot开发的标准过程
1.1 建立父pom管理
在项目的开发过程中使用SpringBoot,通常会引入一个标准父pom配置,如下所示:
<
parent
>
<!-- 引入SpringBoot -->
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-parent
</
artifactId
>
<
version
>1.5.9.RELEASE
</
version
>
</
parent
>
在实际开发Maven项目开发中,往往不同的成员会根据自己的需求来定义自己的父pom,这样就会产生冲突。为了解决这个问题,在SpringBoot里,用户也可以直接以依赖管理的形式使用SpringBoot。
我们建立一个用来管理父pom的Maven的项止xiaoxieboot
1.建立一个Maven项目:xiaoxieboot
注意:建立maven项目的时候packing选择pom
2.对pom.xml做如下配置
<
project
xmlns=
"
http://maven.apache.org/POM/4.0.0
"
xmlns:xsi=
"
http://www.w3.org/2001/XMLSchema-instance
"
xsi:schemaLocation=
"
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd
"
>
<
modelVersion
>4.0.0
</
modelVersion
>
<
groupId
>com.xiaoxie
</
groupId
>
<
artifactId
>
xiaoxieboot
</
artifactId
>
<
version
>0.0.1-SNAPSHOT
</
version
>
<!-- 定义为
pom
类型 -->
<
packaging
>
pom
</
packaging
>
<
name
>
xiaoxieboot
</
name
>
<
properties
>
<
jdk.version
>1.8
</
jdk.version
>
<
spring-boot-dependencies.version
>1.5.9.RELEASE
</
spring-boot-dependencies.version
>
<
project.build.sourceEncoding
>UTF-8
</
project.build.sourceEncoding
>
</
properties
>
<
dependencyManagement
>
<!-- 定义SpringBoot的依赖管理 -->
<
dependencies
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-dependencies
</
artifactId
>
<
version
>${spring-boot-dependencies.version}
</
version
>
<
type
>
pom
</
type
>
<
scope
>import
</
scope
>
</
dependency
>
</
dependencies
>
</
dependencyManagement
>
<!-- 编译配置 -->
<
build
>
<
finalName
>
xiaoxieboot
</
finalName
>
<
plugins
>
<
plugin
>
<
groupId
>org.apache.maven.plugins
</
groupId
>
<
artifactId
>
maven-compiler-
plugin
</
artifactId
>
<
configuration
>
<!-- 源代码开发版本 -->
<
source
>${jdk.version}
</
source
>
<!-- 目标class的编译版本 -->
<
target
>${jdk.version}
</
target
>
<
encode
>${project.build.sourceEncoding}
</
encode
>
</
configuration
>
</
plugin
>
</
plugins
>
</
build
>
</
project
>
3.在xiaoxieboot这个项目上新增一个Maven Module:xiaoxieboot-base
4.编辑xiaoxieboot-base中的pom.xml,在其中添加关于SpringBoot的依赖,在生成的pom中自动添加parent配置
<!-- 定义依赖配置 -->
<
dependencies
>
<
dependency
>
<
groupId
>
junit
</
groupId
>
<
artifactId
>
junit
</
artifactId
>
<
scope
>test
</
scope
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-web
</
artifactId
>
</
dependency
>
</
dependencies
>
注意:在添加了Maven Module后,在xiaoxieboot项目的pom.xml中也会自动添加上<modules>,如下所示:
<
modules
>
<
module
>
xiaoxieboot-base
</
module
>
</
modules
>
5.在xiaoxieboot-base中新增一个controller类:com.xiaoxie.controller.SampleController
package com.xiaoxie.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
//控制器
@EnableAutoConfiguration
//启用自动配置
public
class SampleController {
@RequestMapping(
"/")
//访问映射路径
@ResponseBody
//Restful返回形式
public String index() {
return
"使用Maven子模块来解决POM依赖冲突!";
}
public
static
void main(String[]
args) {
//启动SpringBoot
SpringApplication.
run(SampleController.
class,
args);
}
}
6.运行工程,并访问:http://localhost:8080/
这个时候页面会显示为:
使用Maven子模块来解决POM依赖冲突!
1.2 关于SpringBoot程序测试
从上面我们运行程序来看,在程序开发完成后,在测试程序时需要启动Spring容器。我们在实际上可以使用单元测试的功能来对上面的程序功能进行测试
1.我们在依赖中添加SpringBoot对单元测试的支持
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-test
</
artifactId
>
<
scope
>test
</
scope
>
</
dependency
>
2.新增测试类com.xiaoxie.test.TestSampleController
package com.xiaoxie.test;
import org.junit.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.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.xiaoxie.controller.SampleController;
import junit.framework.TestCase;
@SpringBootTest(classes=SampleController.
class)
//定义需要测试的SpringBoot类
@RunWith(SpringJUnit4ClassRunner.
class)
//使用JUnit单元测试
@WebAppConfiguration
//进行web应用配置
public
class TestSampleController {
@Autowired
//自动注入控制器对象
private SampleController
sampleController;
@Test
//使用JUnit测试
public
void testIndex() {
TestCase.
assertEquals(
sampleController.index(),
"使用Maven子模块来解决POM依赖冲突!");
}
}
3.我们需要对SampleController类中的index方法进行测试的话则只需要选中测试方法testIndex,右键选择JUnit Test即可完成单元测试,如果通过测试则测试进度条显示为绿色且Errors为0

二、SpringBoot注解分析
关于SpringBoot中的注解,我们先了解上面实例程序中的4个注解
注解
|
说明
|
@Controller
|
控制器类的注解,使用这个类的注解就是一个控制器类
|
@EnableAutoConfiguration
|
开启自动配置
|
@RequestMapping("/")
| 设置访问的映射路径,"/"表示指定的路径(http://localhost:8080/) |
@ResponseBody
|
直接返回的数据以字符串或JSON的形式获得
|
上面的几个注解中重点说一下@EnableAutoConfiguration,它为整个SpringBoot启动注解配置。这个注解是要随着程序的主类一起定义的,这个注解有一个前提就是只能扫描在同一程序类包中的配置程序。
对于控制器类,最好是把这些控制器类统一保存在一个包中,如:com.xiaoxie.controller包下,在这样的环境下建议使用@SpringBootApplication注解来实现启动配置。SpringBoot开发过程中,为了简化开发配置,通常会在SpringBoot启动类下创建多个子包,这样子包中的注解就可以自动扫描到,并且可以实现依赖关系的自动配置,那么一般的包结果如下所示
com.xiaoxie
|- SpringBootStartApplicationMain(程序启动类)
|- com.xiaoxie.controller(子包:Controller)
|- BaseController(Controller类)
|- com.xiaoie.service(子包:Service)
|- BaseService(Service类)
所以我们前面的程序可以做如下调整
1.SampleController中不写main方法,只做Controller相关的操作,去掉main方法的同时去掉@EnableAutoConfiguration这个注解。调整为如下
package com.xiaoxie.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
//控制器
//@EnableAutoConfiguration //启用自动配置
public
class SampleController {
@RequestMapping(
"/")
//访问映射路径
@ResponseBody
//Restful返回形式
public String index() {
return
"使用Maven子模块来解决POM依赖冲突!";
}
/*public static void main(String[]
args
) {
//启动SpringBoot
SpringApplication.run(SampleController.class,
args
);
}*/
}
2.在com.xiaoxie这个包下新增一个启动类:SpringBootStartApplication
package com.xiaoxie;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//启动SpringBoot程序,并且可以扫描它的子包
public
class SpringBootStartApplication {
public
static
void main(String[]
args) {
SpringApplication.
run(SpringBootStartApplication.
class,
args);
}
}
接下来访问http://localhost:8080/ 即可
@RestController注解
上面的例子中,我们需要实现Restful显示,可以让@Controller注解与@ResponseBody注解一起使用,这是一种控制器跳转模式,我们也可以使用@RestController注解来作为Restful显示。
在上例中我们新增一个Controller类,MessageController
package com.xiaoxie.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public
class MessageController {
@RequestMapping(
"/showMessage")
public String showMessage() {
return
"showMessage:哈哈哈哈!";
}
}
接下来启动SpringBoot程序,访问http://localhost:8080/showMessage 即可看到浏览器中显示不文本:
showMessage:哈哈哈哈!
我们使用@RsetController注解则可以避免在控制器类的方法上加上@ResponseBody注解
这里有一个问题我们需要正视一下:因为我们在控制器类上加上了@RestController则这个控制器类的所有方法都只能是使用Restful风格,但有时候我们的方法是需要做控制器跳转的这样就做不到了,所以在SpringBoot中使用@RestController注解并不是特别建议。
前面的实例当我们都只能是简单地返回文本信息,我们如何接收传递过来的参数呢?
传递参数到控制器中的最简单方法是在浏览器地址栏上加上参数内容:"访问路径?参数名称=参数值"
在MessageController类中我们再新增一个控制器方法
@GetMapping(
"/showParam")
public String showParam(String
param) {
return
"param=" +
param;
}
启动SpringBoot程序,访问http://loalhost:8080/showParam?param=你好
这个时候在浏览器中会打印 param=你好
这里使用了@GetMapping注解
由于SpringBoot支持Resful风格处理,所以参数的接收可以采用路径参数的形式完成,这个时候需要在控制器方法的参数上使用@PathVariable注解做声明。
在MessageController类中再新增一个控制器方法
@GetMapping(
"/showName/{na}")
public String showName(
@PathVariable(
"na") String
name) {
return
"名称是:" +
name;
}
启动SpringBoot程序,访问http://localhost:8080/showName/小谢
这个时候在浏览器会显示 名称是:小谢
在里在控制器方法参数上使用了@PathVariable注解,同时要注意在@GetMapping中指定的映射路径中进行参数化的部分需要使用{}括起来。
三、SpringBoot的调试
从上面我们所做的实例来看,我们在每添加一个控制器方法或者修改代码后,都需要重新启动SpringBoot容器才能生效,为了解决这种需要反复重启的问题SpringBoot提供了自动加载配置的依赖库来实现代码的动态加载。
我们需要修改pom.xml文件,我们在xiaoxieboot-base项目中添加如下依赖
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>
springloaded
</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-
devtools
</
artifactId
>
</
dependency
>
当我们加上上面两个依赖后,在用户修改项目中程序类的时候会由SpringBoot自动加载更新后的程序代码,同时我们可以看到项目上也标记了[devtools]
问题:如果我们使用的是JDK9的话这个时候启动SpringBoot程序会报错:java.lang.ClassCastException: java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader
解决方案
第一步,把SpringBoot的版本升级,比如我们换为:2.0.5.RELEASE,也就是我们把xiaoxieboot这个父项目中spring-boot-dependencies.version中的版本替换掉
第二步,把xiaoxieboot-base中的pom中springloaded的依赖去掉
这个时候再启动SpringBoot则可以正常,并且当我们修改了项目的源码后也可以正常的自动加载
四、SpringBoot内置对象
在SpringBoot中使用JSP内置对象也可以照SpringMVC同样的方式进行。
我们在控制器的方法上使用参数来接收内置对象
在MessageController类中新增控制器方法:
@GetMapping(
"/object")
public Object innerObject(HttpServletRequest
request,HttpServletResponse
response) {
Map<String,String>
map =
new HashMap<String,String>();
map.put(
"IP地址:",
request.getRemoteAddr());
map.put(
"响应编码:",
response.getCharacterEncoding());
map.put(
"SessionID:",
request.getSession().getId());
map.put(
"项目路径:",
request.getServletContext().getRealPath(
"/"));
return
map;
}
这个时候访问:http://localhost:8080/object
页面打印出来的结果如下:它会以JSON的格式返回
{"响应编码:":"ISO-8859-1","IP地址:":"0:0:0:0:0:0:0:1","SessionID:":"927189FDE42B546501DA376E86DEEF84","项目路径:":"C:\\Users\\adven\\AppData\\Local\\Temp\\tomcat-docbase.10258554538332146160.8080\\"}
不在控制器方法的参数内明确接收内置对象而是使用ServletRequestAttributes的形式获取内置对象
在MessageController类中再新增一个控制器方法
@GetMapping(
"/object1")
public Object innerObject1() {
Map<String,String>
map =
new HashMap<String,String>();
HttpServletRequest
request = ((ServletRequestAttributes)RequestContextHolder.
getRequestAttributes()).getRequest();
HttpServletResponse
response = ((ServletRequestAttributes)RequestContextHolder.
getRequestAttributes()).getResponse();
map.put(
"IP地址:",
request.getRemoteAddr());
map.put(
"响应编码:",
response.getCharacterEncoding());
map.put(
"SessionID:",
request.getSession().getId());
map.put(
"项目路径:",
request.getServletContext().getRealPath(
"/"));
return
map;
}
这个时候访问:http://localhost:8080/object1
页面打印出来的结果如下:它会以JSON的格式返回
{"响应编码:":"ISO-8859-1","IP地址:":"0:0:0:0:0:0:0:1","SessionID:":"927189FDE42B546501DA376E86DEEF84","项目路径:":"C:\\Users\\adven\\AppData\\Local\\Temp\\tomcat-docbase.10258554538332146160.8080\\"}
五、SpringBoot配置环境信息
SpringBoot为了保证尽量减少配置,提供了很多的默认配置,比如:项目默认过行的是8080端口,如果我们需要去调整这些默认配置可以在CLASSPATH下添加application.properties配置文件进行配置。
这里要注意,配置文件的名称一定是application.properties,否则SpringBoot无法加载到配置文件
我们要设置Tomcat的端口号则可以添加如下配置
server.port=80
配置contextpath访问路径
server.servlet.context-path=
/xiaoxie
除了使用application.properties进行配置外,SpringBoot中也可以使用application.yml进行配置
我们把上面的两个配置转为applicaion.yml后配置如下
server:
port: 80
#定义端口号
servlet:
context-path: /xiaoxie
#定义ContextPath
从上面的配置文件结构来看相对于properties文件yml文件的结构更加清晰
关于yml文件:
yml实际上为YAML(Yet Another Markup Languange),它是一种标记语言文件,它是一种结构化的数据文件。
Spring的官方推荐使用yml文件来进行配置定义
注意:当我们的项目中同时存在application.properties,application.yml则会以application.properties作为参考。
六、SpringBoot项目中资源文件的读取
实际的开发过程中,资源文件是必不可少的,一般来说所有的提示信息都是配置在资源文件中的,第二资源文件它是实际国际化技术的主要手段。
如果在SpringBoot项目中进行资源文件的配置?
1.定义资源文件xxx.properties
2.在application.yml文件中进行配置
3.使用MessageSource进行读取
实例说明:
1.在Classpath下新增一个包i18n,并在其下新增Messages.properties
welcome.url=
xiaoxie.com
welcome.msg=
欢迎
{0}
!
2.在application.yml文件中配置资源文件,新增的配置信息如下
spring:
messages:
basename: i18n/Messages
#定义资源文件,如果存在多个时使用,号分隔
3.在控制器类中新增控制器方法测试对资源文件的获取
@Autowired
private MessageSource
messageSrouce;
//自动注入资源对象
@GetMapping(
"/getMessage")
public Object getMessage() {
Map<String,String>
map =
new HashMap<String,String>();
map.put(
"url:",
messageSrouce.getMessage(
"welcome.url",
null, Locale.
getDefault()));
map.put(
"msg:",
messageSrouce.getMessage(
"welcome.msg",
new Object[] {
"小谢"}, Locale.
getDefault()));
return
map;
}
注意:需要在Controller控制器类中注入org.springframework.context.MessageSource接口
3.启动SpringBoot程序并访问:
http://localhost/xiaoxie/getMessage(这里没有端口号8080是因为上一例子中我们在yml文件已经配置了端口号为80,而80端口是默认的端口在访问时可以省略不用输入;其中/xiaoxie路径是因为在yml文件中配置了contextPath为"/xiaoxie"),页面显示内容如下:
{"msg:":"欢迎小谢!","url:":"xiaoxie.com"}
通过上面的例子我们得知如何进行资源文件的读取了,我们看到MessageSrouce的getMessage方法中有一个参数是Locale(这个指定的是语言区域),通过它的传入我们就可以实现国际化了。
怎么实现国际化呢?
首先,我们需要在资源文件所在的位置本置多个资源文件(这些资源文件是指定语言区域的),比如
Messages_zh_CN.properties、Messages_en_US.properties
注意:这些资源文件的baseName是一样的都是Messages
其次,我们在调用MessageSrouce的getMessae方法时Locale参数传入时指定相应的语言区域,比如
map.put(
"msg:",
messageSrouce.getMessage(
"welcome.msg",
new Object[] {
"小谢"}, new Locale("en","US")));
这里有一个点需要特别注意:当我们要使用国际化时有了Messages_zh_CN.properties、Messages_en_US.properties的配置文件但是Messages.properties也必需要存在否则可能在运行项目时提示找不到key
七、Spring配置的整合
在Spring项目中对项目进行配置可以使用xml配置文件或者注解的方式进行,同样在SpringBoot中也是可以使用配置文件及注解的方式进行整合
首先,我们看看如何使用配置文件的方式整合Spring的配置
1.我们新增一个utils包,在其中新增InfoUtils类,com.xiaoxie.utils.InfoUtils
package com.xiaoxie.utils;
public
class InfoUtils {
public String getCopyrightInfo() {
return
"版权信息:xiaoxie";
}
}
2.在classpath路径下新增包spring,并在其中新增一个spring的配置文件spring-utils.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 定义Bean配置 -->
<
bean
class=
"com.xiaoxie.utils.InfoUtils"
id=
"infoUtils"
/>
</
beans
>
3.在controller类中注入上面配置的bean并调用bean对应的方法返回信息
@Autowired
private InfoUtils
infoUtils;
@GetMapping(
"/getCopyright")
public String getCopyrightInfo() {
return
infoUtils.getCopyrightInfo();
}
4.在SpringBoot启动类上新增一个注释以导入Spring的配置文件
@ImportResource(
"classpath:spring/spring_utils.xml")
//这里需要导入Spring配置文件
5.启动SpringBoot并访问:
http://localhost/xiaoxie/getCopyright
在浏览器中会显示信息:
版权信息:xiaoxie
上面的实例中我们使用了xml的配置文件来配置Spring,我们也可以使用注解的方法来进行配置(建议使用方式!!
)
1.修改上列把InfoUtils类上添加注解@Component
2.去掉SpringBoot中导入Spring配置文件的注解@ImportResource
八、SpringBoot打包发布
SpringBoot的包发布过程过程比较简单,只需要在项目中配置好插件,然后包发布执行就可以了。
1.在xiaoxieboot-base项目的pom.xml文件中进行插件的配置
<!-- 对项目打包发布处理 -->
<
build
>
<
plugins
>
<
plugin
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-
maven-
plugin
</
artifactId
>
<
configuration
>
<!-- 配置程序执行的主类 -->
<
mainClass
>com.xiaoxie.SpringBootStartApplication
</
mainClass
>
</
configuration
>
<
executions
>
<
execution
>
<
goals
>
<
goal
>repackage
</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
build
>
2.对项目进行Maven更新,右键--->maven--->Update Project...
3.对项目进行打包处理,右键--->Run As--->Maven build...

注意:JDK的版本要与Maven中配置的默认JDK一致
完成后会在项目的traget目录下生成一个jar包(xiaoxieboot),这里生成的jar文件是:xiaoxieboot.jar
打开cmd,进入到jar所在的目录,运行命令:java -jar xiaoxieboot.jar
在控制台中可以看到相应的启动情况,当正常启动成功后则可以在浏览器中进行访问
要停止服务可以ctrl+c
九、profile配置
考虑到我们开发过程中有不同的运行环境:开发环境、UAT环境、生产环境,以往我们使用maven构建工具进行控制时需要进行大量的配置,SpringBoot为了简化这个问题的处理,提供了profile配置的支持。
我们可以修改我们的配置文件yml文件
#server:
# port: 80 #定义端口号
# servlet:
# context-path: /xiaoxie #定义ContextPath
#spring:
# messages:
# basename: i18n/Messages #定义资源文件,如果存在多个时使用,号分隔
spring:
profiles:
active: dev
#定义默认生效的环境
server:
servlet:
context-path: /xiaoxie
---
spring:
profiles: dev
messages:
basename: i18n/Messages
#定义资源文件,如果存在多个时使用,号分隔
server:
port: 7070
---
spring:
profiles: beta
messages:
basename: i18n/Messages
#定义资源文件,如果存在多个时使用,号分隔
server:
port: 8080
---
spring:
profiles: product
messages:
basename: i18n/Messages
#定义资源文件,如果存在多个时使用,号分隔
server:
port: 80
注意:--- 表示对profile的分隔,这里其实可以理解为有三份配置
接下来我们如果需要在STS(Ecelipse)中运行时选择不同的配置,可以在项目上点击右建--->Run As--->Run Configurations,找到对应Spring Boot App,在其中录入需要进入的profile

如果我们打包成为了jar文件则如何切换profile进行运行呢?
从上面的yml文件我们可以看到默认的生效环境是dev
所以直接执行如下命令则会按dev的环境进行部署:java -jar xiaoxieboot.jar
如查我们需要切换环境部署则可以使用如下命令(比如我们使用product环境):java -jar xiaoxieboot.jar --spring.profiles.active=product