Spring Boot
学习自 B 站 UP 主 编程不良人。。。
springboot 介绍
springboot 引言
Spring Boot 是由 Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的 初始搭建以及开发过程。该框架使用了 特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
springboot(微框架) = springmvc(控制器) + spring core(项目管理)
SSM Spring springmvc mybatis <---- SSM Spring struts2|struts1 mybatis <— SSH Spring Struts Hibernate
springboot 特点
- 创建独立的 Spring 应用程序
- 嵌入的 Tomcat,无需部署 WAR 文件
- 简化 Maven 配置
- 自动配置 Spring,没有 XML 配置
springboot 约定大于配置
项目目录结构:
springboot 项目中必须在 src/main/resources
中 放入 application.yml
(application.properties
)核心配置文件,名字必须为:application
;
springboot 项目中必须在 src/main/java
中所有子包之外构建全局入口类型 xxApplication
,入口类一个 springboot 项目只能有一个。
springboot 入门项目解析
项目结构
// @EnableAutoConfiguration // 作用: 开启自动配置 初始化spring环境 springmvc环境
// @ComponentScan // 作用: 用来扫描相关注解 扫描范围 当前入口类所在的包及子包(com.yusal及其子包)
// 下面的注解的功能是上面两个注解功能之和
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// springApplication: spring应用类 作用: 用来启动springboot应用
// 参数1: 传入入口类 类对象 参数2: main函数的参数
SpringApplication.run(Application.class, args);
}
}
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/hello")
public String hello() {
System.out.println("hello springboot!!!");
return "hello springboot";
}
}
相关注解
@EnableAutoConfiguration
- 作用:开启自动配置 ,根据 pom.xml 文件中依赖自动判断并构建环境
如在第一个环境之中引入了 spring-boot-starter-web, 会自动根据引入的这个依赖构建相关环境(springmvc环境、web容器环境) - 修饰范围:只能用在类上
@ComponentScan
- 作用:用来开启注解扫描
- 修饰范围:只能用在类上
- 扫描注解范围:默认当前包以及当前包下的子包
@SpringBootApplication
:@EnableAutoConfiguration
+ @ComponentScan
@RestController
- 作用:用来实例化当前对象为一个控制器对象,并将类上的所有方法的返回值转为 json,响应给浏览器。
- 修饰范围: 用在类上
- 功能相当于:
@Controller
+@ResponseBody
@Controller
:实例化当前类为一个控制器@ResponseBody
:用来将当前方法返回值转为 json, 相应给浏览器
@RequestMapping
- 作用:用来加入访问路径
- 修饰范围:类(加入命名空间)、方法上(指定具体路径)
- 同类注解:
@GetMapping
:作用: 限定请求方式只能是GET,并指定路径;修饰范围:方法上
@PostMapping
@DeleteMapping
@PutMapping
main
方法的作用:指定通过标准 java 入口方式委托给 SpringApplication
,并告知当前 springboot
主应用类是谁,从而启动 springboot 中 tomcat 容器;
args
作用:可以在启动时使用外部参数
starter
:启动器,springboot-starter-xxx Starters 是一组方便的依赖关系描述符。
springboot 配置文件的拆分
在实际开发过程中生产环境和测试环境有可能是不一样的,因此将生产中的配置和测试中的配置拆分开,是非常必要的;在 springboot 中也提供了配置文件拆分的方式。这里以生产中项名名称不一致为例:
主配置文件:application.properties
# 延迟加载
spring.main.lazy-initialization=true
# 使用测试环境配置
spring.profiles.active=dev
测试配置文件:application-dev.properties
server.servlet.context-path=/springboot
server.port=8989
生产配置文件:application-prod.properties
server.servlet.context-path=cmfz
server.port=8080
springboot 创建自定义简单对象
管理单个对象 User
在 springboot 中可以管理自定义的简单组件对象的创建可以直接使用注解形式创建。
entity
包:User.java
public class User {
private String id;
private String name;
public User() {
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
或者通过 lombok 的插件,用注解创建项目:
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String id;
private String name;
}
service
包:UserService.java
、UserServiceImpl.java
public interface UserService {
void save(String name);
}
@Service // 将业务层交给springboot管理
public class UserServiceImpl implements UserService {
@Override
public void save(String name) {
System.out.println("name = " + name);
}
}
controller
包:HelloController.java
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private User user; // 可以获取对象
@Autowired
private UserService userService; //
@GetMapping("/hello")
public String hello() {
System.out.println(user);
userService.save("振宇"); // 管理单个对象
return "hello spring boot!!!";
}
}
User{id='null', name='null'}
name = 振宇
管理多个对象 User、Calender
在 springboot 中如果要管理 复杂对象 必须使用 @Configuration + @Bean
注解进行管理
在管理单个对象的继承上增加了 configs
包:BeanConfigs.java
注意:
@Configuration
配置注解主要用来生产多个组件交给工厂管理 (注册形式)@Component
用来管理单个组件 (包扫描形式)
// @Component 也可以, 不推荐
@Configuration // 推荐
public class BeanConfigs {
@Bean // @Bean 将当前返回值作为工厂中的一个对象进行管理
public User getUser() {
return new User();
}
@Bean //(name = "aaa") // 用来将该方法的返回值交给springboot管理 在工厂中默认标识: 类名(首字母小写)
@Scope("prototype") // prototype表示多例; 默认是singleton, 单例的
public Calendar getCalendar() {
return Calendar.getInstance();
}
}
controller
包的 HelloController.java
:
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private User user;
@Autowired
private UserService userService;
@Autowired
private Calendar calendar1;
@Autowired
private Calendar calendar2;
@GetMapping("/hello")
public String hello() {
System.out.println("hello spring boot!!!");
System.out.println(user);
userService.save("振宇"); // 管理单个对象
System.out.println(calendar1.getTime()); // 管理多个对象
System.out.println(calendar1 == calendar2); // 默认是单例的, 需要设置prototype
return "hello spring boot!!!";
}
}
hello spring boot!!!
User{id='null', name='null'}
name = 振宇
Fri May 08 22:22:20 CST 2020
false
springboot 中的注入
springboot 中提供了两种注入方式: 基本属性注入、对象注入
基本属性注入 @Value
application.properties
中配置:
server.port = 8989
# 属性注入
name = zhenyu
bir = 2012/12/12 12:12:12
strs = aa, bb, cc
list = zhangsan, lisi, wangwu
maps = {'aa':'xiaoyi', 'bb':'xiaoer', 'cc':'xiaosan'}
基本属性注入:使用注解 @Value("${xxx}")
@RestController
@RequestMapping("hello")
public class HelloController {
@Value("${name}")
private String name;
@Value("${server.port}")
private int port;
@Value("${bir}")
private Date bir;
@Value("${strs}")
private String[] strs;
@Value("${list}")
private List<String> list;
@Value("#{${maps}}") // map注入取值有点特殊
private Map<String, String> maps;
@GetMapping("hello")
public String hello() {
System.out.println("name = " + name);
System.out.println("port = " + port);
System.out.println("time = " + bir);
for (String str : strs) {
System.out.println(str);
}
list.forEach( v -> System.out.println(v));
maps.forEach((k, v) -> {
System.out.println("k = " + k + ", v = " + v);
});
return "hello spring boot!";
}
}
name = zhenyu
port = 8989
time = Wed Dec 12 12:12:12 CST 2012
aa
bb
cc
zhangsan
lisi
wangwu
k = aa, v = xiaoyi
k = bb, v = xiaoer
k = cc, v = xiaosan
User(id=1721, age=20)
对象方式注入 @ConfigurationProperties(prefiex=“xx”)
application.properties
中配置:
# 自定义对象属性注入
user.id = 1721
user.name = zhenyu
user.age = 20
user.bir = 2012/12/12 12:12:12
对象方式注入使用注解:@ConfigurationProperties(prefix="前缀")
@ToString
@Data // 必要
@Component // @Configuration 也可以
@ConfigurationProperties(prefix = "user") // 必要
public class User {
private String id;
private String name;
private Integer age;
private Date bir;
}
控制器中使用:@Autowired
完成自动注入;
@RestController
@RequestMapping("hello")
public class HelloController {
@Autowired
private User user;
@GetMapping("hello")
public String hello() {
System.out.println(user);
return "hello spring boot!";
}
}
User(id=1721, name=yusael, age=20, bir=Wed Dec 12 12:12:12 CST 2012)
提示:可以通过引入依赖构建自定义注入元数据(在 application.properties
中写会有提示,不引入也可以)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
springbootv中两种模板配置
集成jsp模板
wait…
集成thymelaf模板
wait…
springboot 继承 Mybatis
可以看看这个:一个项目了解 SpringBoot 集成 MyBatis
springboot 开启热部署
jsp 页面热部署
在 springboot 中默认对 jsp 运行为生产模式,不允许修改内容保存后立即生效,因此在开发过程需要调试 jsp 页面每次需要重新启动服务器,这样极大影响了我们的效率,为此 springboot 中提供了可以将默认的生产模式修改为调试模式,改为调试模式后就可以保存立即生效。只需要需要在配置文件中加入如下配置即可修改为调试模式。
# 开启jsp页面的热部署
server.servlet.jsp.init-parameters.development=true
springboot 中 devtools 热部署
为了进一步提高开发效率,springboot 为我们提供了全局项目热部署,日后在开发过程中修改了部分代码以及相关配置文件后,不需要每次重启使修改生效,在项目中开启了 springboot 全局热部署之后只需要在修改之后等待几秒即可使修改生效。
在项目中添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
设置idea中支持自动编译:
- 开启自动编译
Preferences
|Build
,Execution
,Deployment
|Compiler
勾选上Build project automatically
这个选项 - 开启允许在运行过程中修改文件
ctrl + alt + shift + /
选择1.Registry
勾选compiler.automake.allow.when.app.running
这个选项
启动项目检测热部署是否生效:
默认没有开启热部署,启动项目时显示的是 [ main]
开启热部署以后,启动项目显示的是:[ restartedMain]
logback日志的集成
Logback 是由 log4j 创始人设计的又一个开源日志组件。目前,logback 分为三个模块:logback-core,logback-classic 和 logback-access。是对 log4j 日志展示进一步改进。
日志的级别:DEBUG
< INFO
< WARN
< ERROR
< OFF
,日志级别越高输出的日志信息越少。
项目中日志分两类:
rootLogger
:用来监听项目中所有的运行日志,包括引入依赖 jar 中的日志。logger
:用来监听项目中指定包中的日志信息。
logback 配置文件
logback 的配置文件必须放在项目根目录中 且名字必须为 logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义项目中日志输出位置-->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--定义项目的日志输出格式-->
<!--定义项目的日志输出格式-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern> [%p] %d{yyyy-MM-dd HH:mm:ss} %m %n</pattern>
</layout>
</appender>
<!--项目中跟日志控制-->
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
<!--项目中指定包日志控制-->
<logger name="com.baizhi.dao" level="DEBUG"/>
</configuration>
具体类中使用日志
@Controller
@RequestMapping("/hello")
@Slf4j // 自动声明日志对象
public class HelloController {
//声明日志成员, 可使用 @Slf4j 代替
// private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("======hello world=======");
logger.debug("DEBUG");
logger.info("INFO");
logger.warn("WARN");
logger.error("ERROR");
return "hello";
}
}
使用默认日志配置
# 配置根日志等级
logging.level.root=info
# 配置子日志等级
logging.level.com.yusael.dao=debug
logging.level.com.yusael.controller=debug