Spring boot 学习笔记

本文是Spring Boot的学习笔记,涵盖了项目初始化、开发环境要求、Servlet容器、首个HelloWorld应用、Spring Boot Web开发,包括热部署、静态资源映射、中文乱码解决方案等,还涉及了Spring Boot集成spring-data-jpa、使用RAP2、RESTful接口设计、YAML配置、单元测试、日志管理和微服务等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring boot 学习笔记

参考资料

https://spring.io/projects/spring-boot/#learn

官方文档和API

2.2.0 CURRENT GA Reference Doc. API Doc.
2.2.1 SNAPSHOT Reference Doc. API Doc.
2.1.10 SNAPSHOT Reference Doc. API Doc.
2.1.9 GA Reference Doc. API Doc.
1.5.22 GA Reference Doc. API Doc.

项目初始化

在线初始化:https://start.spring.io/

Eclipse 安装Spring Tools插件 或者下载Spring官方的STS整合版。

IntelliJ IDEA 安装Spring Assistant插件。

Spring Boot CLI初始化项目:

You can download the Spring CLI distribution from the Spring software repository:

开发系统要求

使用Spring Boot 2.1.9.RELEASE

JDK版本:

Java 8 and is compatible up to Java 12 (included).

Spring版本:

Spring Framework 5.1.10.RELEASE or above is also required.

构建工具版本:

Build ToolVersion
Maven3.3+
Gradle4.4+

Servlet 容器

Spring Boot supports the following embedded servlet containers:

NameServlet Version
Tomcat 9.04.0
Jetty 9.43.1
Undertow 2.04.0

You can also deploy Spring Boot applications to any Servlet 3.1+ compatible container.

第一个HelloWorld

参考官方文档10. Installing Spring Boot

步骤:

  1. 新建一个基于Maven 的 Spring boot Java 工程

  2. 自动生成启动类

  3. 配置文件中修改默认端口

  4. 编写Controller类

  5. 运行程序

下面是一个典型的程序结构:

com
	+- example
		+- myproject
			+- Application.java
			|
			+- domain
				| +- Customer.java
				|
			+- repository
				| +- CustomerRepository.java
				|
			+- service
				| +- CustomerService.java
				|
			+- web
				+- CustomerController.java

Application.java 将声明 main 方法和 @SpringBootApplication

1.使用插件或者在线网页进行spring boot项目的初始化

  • jdk版本 8

  • maven项目

  • java语言

  • 设置项目的路径等配置

2.选择spring boot版本 和 工具支持

  • 创建spring web项目 就要勾选 Web>Spring Web

  • 以后需要spring data jpa项目 就要勾选 SQL>Spring Data JPA -对应需要配置数据源

  • 如此类推

3.自动生成程序入口启动类:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootDemo01Application {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemo01Application.class, args);
	}

}

通常建议将应用的main类放到其他类所在包的顶层(root package),项目启动时自动扫描main启动类所在的根路径com.example.demo下所有带spring组件注解的类:

@Component -无法界定属于下面哪个具体的层的时候使用,例如:AOP、LOG、工具类…

@Repository - 持久层
@Service -业务层
@Controller -控制层
@RestController -控制层-Restful风格API设计

4.默认配置文件

src\main\resources\application.properties

可以修改下端口号防止端口占用:

server.port=8081

5.自定义一个web层类

package com.example.demo.hello.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController 
{
	@GetMapping("/hello")
	public String hello() {
		
		return "Hello World!";
	}
}

6.启动项目

选中 SpringBootDemo01Application.java文件 Run as…>Spring Boot App

启动成功后打开浏览器访问:http://localhost:8081/hello

7.Maven介绍

Maven用户可以继承 spring-boot-starter-parent 项目来获取合适的默认设
置。该parent项目提供以下特性:

  • 默认编译级别为Java 1.6

  • 源码编码为UTF-8

  • 一个Dependency management节点,允许你省略常见依赖的 标
    签,继承自 spring-boot-dependencies POM。

  • 恰到好处的资源过滤

  • 恰到好处的插件配置(exec插件,surefire,Git commit ID,shade)

  • 恰到好处的对 application.properties 和 application.yml 进行筛选,

    包括特定profile(profile-specific)的文件,比如 applicationfoo.
    properties 和 application-foo.yml

    最后一点:由于配置文件默认接收Spring风格的占位符( ${…} ),所以Maven
    filtering需改用 @…@ 占位符(你可以使用Maven属性 resource.delimiter 来覆
    盖它)。

继承starter parent
如果你想配置项目,让其继承自 spring-boot-starter-parent ,只需
将 parent 按如下设置:

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

注:你应该只需在该依赖上指定Spring Boot版本,如果导入其他的starters,放心
的省略版本号好了。更多starters :参考官方文档 Table 13.1. Spring Boot application starters

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

改变Java版本

<properties>
<java.version>1.8</java.version>
</properties>

使用Spring Boot Maven插件

Spring Boot包含一个Maven插件,它可以将项目打包成一个可执行jar。如果想使用
它,你可以将该插件添加到 节点处:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

注:如果使用Spring Boot starter parent pom,你只需添加该插件而无需配置它,除非你想改变定义在partent中的设置。

Spring Boot Web开发

SpringBoot热部署spring-boot-devtools

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<optional>true</optional>
	</dependency>

在web开发中,静态资源的访问是必不可少的,如:图片、js、css 等资源的访问。spring Boot 对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求。

默认静态资源映射

一、Spring Boot 对静态资源映射提供了默认配置

Spring Boot 默认将 /** 所有访问映射到以下目录:

v classpath:/static

v classpath:/public

v classpath:/resources

v classpath:/META-INF/resources

如果上述目录有多张同名不同内容的的图片fengjing.jpg,当我们访问地址 http://localhost:8080/fengjing.jpg 的时候,显示哪张图片?

优先级顺序为

​ META-INFO/resources > resources > static > public

如:在resources目录下新建 META-INFO/resources 、public、resources、static 四个目录,并分别放入 a.jpg b.jpg c.jpg d.jpg 四张不同的图片:

浏览器分别访问:

http://localhost:8081/a.jpg

http://localhost:8081/b.jpg

http://localhost:8081/c.jpg

http://localhost:8081/d.jpg

均能正常访问相应的图片资源。那么说明,Spring Boot 默认会挨个从META-INFO/resources 、 resources 、static、public 里面找是否存在相应的资源,如果有则直接返回。

二、自定义静态资源映射

在实际开发中,可能需要自定义静态资源访问路径,那么可以继承WebMvcConfigurerAdapter来实现。

第一种方式:静态资源配置类

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
      //将所有/static/** 访问都映射到classpath:/static/ 目录下
       registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
  }
}

访问:http://localhost:8081/static/c.jpg 能正常访问static目录下的c.jpg图片资源。

第二种方式:在application.properties配置

在application.properties中添加配置:

spring.mvc.static-path-pattern=/static/**

重启项目,访问:http://localhost:8081/static/c.jpg 同样能正常访问static目录下的c.jpg图片资源。

Spring Boot 中文乱码解决

中文乱码可能发生的环境:

1.数据库编码

2.IDE工具编码

3.项目文件编码

4.项目Web开发设置

4.部署容器端口编码

5.服务器字体支持

一、spring boot项目修改application.properties配置文件

增加如下配置:

spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8

二、响应时发生乱码?

此时拦截器中返回的中文已经不乱码了,但是controller中返回的数据依旧乱码。

修改controller的@RequestMapping修改如下:

@RequestMapping(value = "/listForDoing", method=RequestMethod.POST, produces="application/json;charset=UTF-8")

这种方法的弊端是限定了数据类型,更好的办法是配置全局编码控制:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

	@Bean
	public HttpMessageConverter<String> responseBodyConverter() {
		 StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
		 return converter;

	 }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
       converters.add(responseBodyConverter());
    }
}

便可以解决SpringBoot的中文乱码问题了。

三、Spring Boot使用FastJson中文乱码解决:

http://412887952-qq-com.iteye.com/blog/2413390

Spring Boot 集成 spring-data-jpa

步骤:

1.在pom.xml文件中添加Spring Boot Maven依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

2.配置数据源

#mysql datasource
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=GMT&characterEncoding=utf-8 
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver

#spring data jpa & mysql
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl


hibernate.implicit_naming_strategy解释是:
当一个实体没有显式地命名它映射到的数据库表时,我们需要隐式地确定该表的名称。或者当特定属性没有显式地命名它映射到的数据库列时,我们需要隐式地确定该列的名称。说的简单点就是表或者属性没有指定使用名称,我的理解就是没有用@TableName和@Column。(When an entity does not explicitly name the database table that it maps to, we need to implicitly determine that table name. Or when a particular attribute does not explicitly name the database column that it maps to, we need to implicitly determine that column name.)它有以下5个属性,由于篇幅有限(我太懒-.-)。并且没有得出具体结论:

  • 1.org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl

  • 2.org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

  • 3.org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl

  • 4.org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl

  • 5.org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    但是我们依然可以自己修改命名策略。然后在配置文件中设置自己的命名策略

hibernate.physical_naming_strategy的解释是:
used to convert a “logical name” (either implicit or explicit) name of a table or column into a physical name (e.g. following corporate naming guidelines),翻译后:物理命名策略,用于转换“逻辑名称”(隐式或显式)的表或列成一个物理名称。这个 physical_naming_strategy 命名策略有两个子属性,如下:

  • 1.PhysicalNamingStrategyStandardImpl:不做修改,直接映射
    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  • 2.SpringPhysicalNamingStrategy:在进行领域映射时,首字母小写,大写字母变为下划线加小写
    ex: LoginName --> login_name
    spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

3.编写domain、repository、service、web(Controller)层

domain

package com.example.demo.hello.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_hello")
public class Hello 
{
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long id;
	private String msg;
	private String myTestMsg;
	
	public Long getId() {
		return id;
	}
	public String getMsg() {
		return msg;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	public String getMyTestMsg() {
		return myTestMsg;
	}
	public void setMyTestMsg(String myTestMsg) {
		this.myTestMsg = myTestMsg;
	}	
}

repository层

package com.example.demo.hello.repository;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.hello.domain.Hello;

/**
 * PagingAndSortingRepository
 * 	基础CRUD功能
 * 	分页+排序功能
 * 	自定义查询功能
 * 	统计分析功能
 */
@Repository
public interface HelloRepository 
	extends PagingAndSortingRepository<Hello, Long>{

}

service层

package com.example.demo.hello.service;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import com.example.demo.hello.domain.Hello;

public interface IHelloService 
{
	public void saveOrUpdate(Hello hello);
	public void delete(Hello hello);
	public Hello findOne(Long id);
	public Page<Hello> findPage(Pageable pageable);
}
package com.example.demo.hello.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.example.demo.hello.domain.Hello;
import com.example.demo.hello.repository.HelloRepository;

@Service
public class HelloService implements IHelloService
{
	@Autowired
	private HelloRepository helloRepository;

	@Override
	public void saveOrUpdate(Hello hello) {
		helloRepository.save(hello);
	}

	@Override
	public void delete(Hello hello) {
		helloRepository.delete(hello);
	}

	@Override
	public Hello findOne(Long id) {
		return helloRepository.findById(id).get();
	}

	@Override
	public Page<Hello> findPage(Pageable pageable) {
		return helloRepository.findAll(pageable);
	}
}

web(Controller) 层

package com.example.demo.hello.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.hello.domain.Hello;
import com.example.demo.hello.service.IHelloService;

@RestController("/hello")
public class HelloController 
{
	@Autowired
	private IHelloService helloService;
	
	@PostMapping
	public void save(Hello hello) {// id = null
		 helloService.saveOrUpdate(hello);
	}
	
	@PutMapping
	public void update(Hello hello) {// id = 1
		 helloService.saveOrUpdate(hello);
	}
	

	@DeleteMapping
	public void delete(Long id) {
		Hello hello = helloService.findOne(id);
		if(null!=hello)
		 helloService.delete(hello);
	}
	
	@GetMapping
	public Hello findOne(Long id) {
		return helloService.findOne(id);
	}
}

4.运行程序,并使用postman调试后台:

POST:http://localhost:8081/hello?msg=你好springboot!

PUT:http://localhost:8081/hello?id=1&msg=我们更新msg字段

GET:http://localhost:8081/hello?id=1

DELETE:http://localhost:8081/hello?id=1

RAP2 快速入门

RAP是一个可视化接口管理工具 通过分析接口结构,动态生成模拟数据校验真实接口正确性, 围绕接口定义,通过一系列自动化工具提升我们的协作效率

可视化编辑,完善的版本控制各种格式的导入导出。让前后端约定接口的工作变得十分简单。

RAP会自动根据接口文档生成Mock接口(前端使用),这些接口会自动生成模拟数据,支持复杂的生成逻辑。

使用RESTful的风格来开发接口

1.先从传统设计接口的方式来看:

新增一个员工:http://www.demo.cn/finance/employee/createEmp

删除一个员工:http://www.demo.cn/finance/employee/deleteEmp

修改一个员工:http://www.demo.cn/finance/employee/updateEmp

获取员工列表:http://www.demo.cn/finance/employee/listEmp

一个非常简单的需求产生的问题:

1.每一个操作,都需要一个独立的url去操作,因为我们对员工的动作都需要反映在url里面.

2.会产生大量的url,非常不方便接口的维护和文档的维护

3.如果有不同的响应方式,我们可能需要额外的参数,甚至不同的url来描述

4.请求参数包含在请求地址中,无法针对性做缓存

2.使用RESTful风格的接口

接口 :http://www.demo.cn/finance/employee

新增一个员工:POST

删除一个员工:DELETE /id

修改一个员工:PUT /id

获取员工列表:GET

获取一个员工列表:GET /id

通过HTTP的请求方式来给予这些请求的不同含义,动作设计.

使用YAML代替Properties

Spring Boot单元测试(Mock)

https://www.cnblogs.com/a8457013/p/7825087.html

https://blog.youkuaiyun.com/liuchuanhong1/article/details/53495004

SpringBoot的日志管理

SpringBoot关于日志的官方文档

实现日志管理的三种方式

  • 1.使用Logback自定义配置实现高级日志
  • 2.使用SLF4J API输出日志
  • 3.使用@Slf4j注解

扩展阅读:

日志级别的选择:Debug、Info、Warn、Error还是Fatal

https://blog.youkuaiyun.com/qq_27088383/article/details/52163388

springBoot完美配置log4j2

https://blog.youkuaiyun.com/V_Come_On/article/details/79408773

Spring AOP实现后台管理系统日志管理

https://blog.youkuaiyun.com/myron_007/article/details/54927529

Spring Boot 日志配置(超详细)

https://blog.youkuaiyun.com/Inke88/article/details/75007649

spring-boot-fileupload文件上传

spring-boot-https协议

spring-boot-redis分布式集群

spring-boot-ehcache缓存

spring-boot-websocket网络通信协议

spring-boot-mybatis

SpringBoot与MicroService微服务

http://spring.io/blog/2015/07/14/microservices-with-spring

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值