在创建好的工程中不需要创建SpringConfig和SpringMvcConfig配置类
创建好的项目会自动生成其他的一些文件,而这些文件目前对我们来说没有任何作用,所以可以将这些文件删除。
可以删除的目录和文件如下:
.mvn
.gitignore
HELP.md
mvnw
mvnw.cmd
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("id ==> "+id);
return "hello , spring boot!";
}
}
报错原因:SpringBoot 3.0以上版本要求JDK 17以上,jdk版本1.8 与 spring boot 3.0.1 版本不匹配
SpringBoot 对比Spring
基于Idea的 Spring Initializr 快速构建 SpringBoot 工程时需要联网。
官网:https://spring.io/projects/spring-boot
进入到 SpringBoot 官网后拖到最下方,点击 Spring Initializr
配置:
以上步骤完成后就可以生成 SpringBoot 工程了。在页面的最下方点击 GENERATE CTRL + 回车 按钮生成工程并下载到本地
打开下载好的压缩包可以看到工程结构和使用 Idea 生成的一模一样
问题:
以后我们和前端开发人员协同开发,而前端开发人员需要测试前端程序就需要后端开启服务器,这就受制于后端开发人员。为了摆脱这个受制,前端开发人员尝试着在自己电脑上安装 Tomcat 和 Idea ,在自己电脑上启动后端程序,这显然不现实。
解决:
我们后端可以将 SpringBoot 工程打成 jar 包,该 jar 包运行不依赖于 Tomcat 和 Idea 这些工具也可以正常运行,只是这个 jar 包在运行过程中连接和我们自己程序相同的 Mysql 数据库即可。这样就可以解决这个问题,如下图:
打包:
打包package前先clean是好习惯
先终止当前运行的项目。由于我们在构建 SpringBoot 工程时已经在 pom.xml 中配置了spring-boot-maven-plugin插件
//spring-boot-maven-plugin插件打包时需要的
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
注意:该插件必须配置,不然打好的 jar 包也是有问题的。
所以我们只需要使用 Maven 的 package 指令打包就会在 target 目录下生成对应的 Jar 包
进入 jar 包所在位置,地址栏输入cmd回车,在 命令提示符 中输入如下命令:
java -jar springboot_01_quickstart-0.0.1-SNAPSHOT.jar
输入s然后点个Tab键就可以直接: springboot_01_quickstart-0.0.1-SNAPSHOT.jar
然后postman发请求,可以看到命令行里输出后端信息,postman展示响应信息。
非springboot的maven是不能用java -jar命令的
我们使用 Spring Initializr 方式创建的 Maven 工程的的 pom.xml 配置文件中自动生成了很多包含 starter 的依赖
这些依赖就是启动依赖
从上面的文件中可以看到指定了一个父工程,我们ctrl+b进入到父工程,发现父工程中又指定了一个父工程
再进入到该父工程中,在该工程中我们可以看到配置内容结构
properties 标签中定义了各个技术软件依赖的版本,避免了我们在使用不同软件技术时考虑版本的兼容问题
在 properties 中我们找 servlet 和 mysql 的版本如下图
爷工程pom.xml里依赖管理标签:
dependencyManagement 标签是进行依赖版本锁定,但是并没有导入对应的依赖。
如果我们工程需要哪个依赖只需要引入依赖的 groupid 和 artifactId 不需要定义 version
build 标签中也对插件的版本进行了锁定
在我们创建的工程中的 pom.xml 中配置了spring-boot-starter-web依赖:
进入到该依赖,查看 pom.xml 的依赖会发现它引入了引入了 spring-web 和 spring-webmvc 的依赖,这就是为什么我们的工程中没有依赖这两个包还能正常使用 springMVC 中的注解的原因。
而依赖 spring-boot-starter-tomcat ,从名字基本能确认内部依赖了 tomcat,所以我们的工程才能正常启动。
结论:以后需要使用技术,只需要引入该技术对应的起步依赖即可
同样方法,spring-boot-starter-test依赖里有spring-test等依赖。
starter
parent
实际开发
使用任意坐标时,仅书写GAV中的G和A,V由SpringBoot提供
G:groupid;A:artifactId;V:version
如发生坐标错误,再指定version(要小心版本冲突)
辅助功能
在starter-web中引入了tomact starter就可以让程序内置了一个tomcat服务器,这个功能就是辅助功能(不是用来做程序的,是用来启动程序的),不能提供业务功能(如导入junit能做测试,导入logback能做日志)
创建的每一个 SpringBoot 程序时都包含一个类似于下面的类,我们将这个类称作引导类、主启动类
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
因为我们在 pom.xml 中配置了 spring-boot-starter-web 依赖,而该依赖通过前面的学习知道它依赖 tomcat ,所以运行 main 方法就可以使用 tomcat 启动咱们的工程。
使用spring-boot-starter-web 依赖实现内置Tomcat服务器,是springboot带来的辅助功能。
现在我们启动工程使用的是 tomcat 服务器,那能不能不使用 tomcat 而使用 jetty 服务器。
jetty 在我们 maven 高级时讲 maven 私服使用的服务器,比Tomcat更轻量级,可扩展性强,谷歌应用引擎已全面切换为Jetty,但目前大型应用一般用的还是Tomcat。
而要切换 web 服务器就需要使用 exclusion 标签将默认的 tomcat 服务器给排除掉。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcatartifactId>
<groupId>org.springframework.bootgroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
dependency>
server.port=80
server:
port: 81
server:
port: 82
SpringBoot 程序的配置文件名必须是 application ,只是后缀名不同而已
自动提示功能消失解决方案:
在配置文件中输入port,如果没有提示,可以使用以下方式解决
点击绿叶图标追加配置文件:
点击加号选择要添加的配置文件:
SpringBoot三种配置文件加载顺序(了解)
SpringBoot 内置属性过多,且所有属性集中在一起修改,在使用时,通过提示键+关键字修改属性
logging:
level:
root: info
核心规则:数据前面要加空格与冒号隔开
【示例】
enterprise:
name: itcast
age: 16
tel: 4006184000
subject:
- Java
- 前端
- 大数据
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("id ==> "+id);
return "hello , spring boot!";
}
}
在 com.zs.domain 包下创建一个名为 Enterprise 的实体类等会用来封装数据
public class Enterprise {
private String name;
private int age;
private String tel;
private String[] subject;
//setter and getter
//toString
}
在 resources 下创建一个名为 application.yml 的配置文件
lesson: SpringBoot
server:
port: 80
enterprise:
name: itcast
age: 16
tel: 4006184000
subject:
- Java
- 前端
- 大数据
方式二:封装全部数据到Environment对象(封装读取全部数据)
方式三:自定义对象封装指定数据(常用)
自定义对象封装数据警告解决方案
以后在工作中,对于开发环境、测试环境、生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要该配置,将环境的配置改为线上环境的
来回的修改配置会很麻烦,而 SpringBoot 给开发者提供了多环境的快捷配置,需要切换环境时只需要改一个配置即可。不同类型的配置文件多环境开发的配置都不相同
连接符—作用:单文件中可以通过—实现多文件的效果
#设置启用的环境
spring:
profiles:
active: dev #表示使用的是开发环境的配置
---
#开发
spring:
profiles: dev
server:
port: 80
---
#生产
spring:
profiles: pro
server:
port: 81
---
#测试
spring:
profiles: test
server:
port: 82
---
主启动配置文件:application.properties
环境分类配置文件:application-pro.properties
环境分类配置文件:application-dev.properties
环境分类配置文件:application-test.properties
使用 SpringBoot 开发的程序以后都是打成 jar 包,通过 java -jar xxx.jar …的方式启动服务的
打包时注意两个坑:
坑一: 执行package命令前先执行以下clean命令,避免上一次的结果影响本次操作。
坑二:配置文件中偶尔可能写中文,会导致打包失败,更改一下配置
带参数启动SpringBoot:
java –jar springboot.jar –-spring.profiles.active=test
java –jar springboot.jar –-server.port=88
java –jar springboot.jar –-server.port=88 –-spring.profiles.active=test
注意: 命令行启动参数都是临时更改,不影响源代码
进行测试后就会发现命令行设置的端口号优先级高(也就是使用的是命令行设置的端口号),配置的优先级SpringBoot官网上进行了说明
Maven和springboot都有profile环境配置,在实际开发中,应该maven为主,springboot为辅。springboot读取maven多环境配置
执行Maven打包命令
问题:由于测试环境和开发环境的很多配置都不相同,所以测试人员在运行我们的工程时需要临时修改很多配置
解决方案:针对这种情况,SpringBoot 定义了配置文件不同的放置的位置;而放在不同位置的优先级时不同的。
SpringBoot 中4级配置文件放置位置:
一二级留作系统打包后设置通用属性
三四级用于系统开发阶段设置通用属性
注意:SpringBoot 2.5.0版本存在一个bug,我们在使用这个版本时,需要在 jar 所在位置的 config 目录下创建一个任意名称的文件夹
SpringBoot 整合 junit:
public interface BookService {
public void save();
}
@Service
public class BookServiceImpl implements BookService {
@Override
public void save() {
System.out.println("book service is running ...");
}
}
在test/java目录下创建com.zs包,在该包下编写测试类
@SpringBootTest
class Springboot07TestApplicationTests {
@Autowired
private BookService bookService;
@Test
public void save() {
bookService.save();
}
}
注意:这里的引导类所在包必须是测试类所在包及其子包。
例如:引导类所在包是 com.itheima;测试类所在包也是 com.itheima
如果不满足这个要求的话,就需要在使用 @SpringBootTest 注解时,使用 classes 属性指定引导类的字节码对象。如 @SpringBootTest(classes = Springboot07TestApplication.class)
SpringBoot整合SSM两个关键步骤:@Mapper和yml配置数据源
public class Book {
private Integer id;
private String name;
private String type;
private String description;
//setter and getter.....
//toString
}
com.mysql.jdbc.Driver与com.mysql.cj.jdbc.Driver的区别:
JDBC连接Mysql5需用com.mysql.jdbc.Driver
JDBC连接Mysql6需用com.mysql.cj.jdbc.Driver,同时url需要指定时区serverTimezone。
设定时区时,serverTimezone=UTC比中国时间早8个小时,若在中国,可设置serverTimezone=Asia/Shanghai
注意:
SpringBoot 版本低于2.4.3(不含),Mysql驱动版本大于8.0时,需要在url连接串中配置时区 jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC,或在MySQL数据库端配置时区解决此问题
@Mapper
public interface BookDao {
@Select("select *from tbl_book where id = #{id}")
public Book getById(Integer id);
}
@SpringBootTest
class SpringbootMybatisApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void testGetById() {
Book book = bookDao.getById(1);
System.out.println(book);
}
}
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.16version>
dependency>
server:
port: 80
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?servierTimezone=UTC
username: root
password: root
//TODO 添加@Mapper
@Mapper
public interface BookDao {
@Insert("insert into tbl_book values (null, #{type}, #{name}, #{description})")
int save(Book book);
@Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
int update(Book book);
@Delete("delete from tbl_book where id = #{id}")
int delete(Integer id);
@Select("select * from tbl_book where id = #{id}")
Book getById(Integer id);
@Select("select * from tbl_book")
List<Book> getAll();
}
@SpringBootTest
public class BookServiceTest {
@Autowired
private BookService bookService;
@Test
public void testGetById(){
Book book = bookService.getById(2);
System.out.println(book);
}
@Test
public void testGetAll(){
List<Book> bookList = bookService.getAll();
System.out.println(bookList);
}
}