一、Spring开发历程
- 第一阶段:XML配置
- spring1.x时代,项目中都是XML文件配置
- 写一个类就要想着让spring帮助你管理,就得到了配置文件中创建bean,需要频繁的在业务代码和配置文件之间来回切换
- 类与类之间的依赖注入,属性的赋值等等,都需要在配置文件中手动配置,被管理的bean多了,难免出错
- 第二阶段:注解配置
- spring2.x时代,随着JDK1.5 带来的注解支持,业务组件会采用注解,但是数据源、试图解析器等等还需要在配置文件中配置,注解+XML配置
- 第三阶段:java配置
- sppring3.0 引入了基于java的配置能力,用java类来替代XML配置文件
- spring4.x以及springboot中都推荐java配置
二、springboot介绍
-
springboot并不是一门新技术,只是将之前常用的spring、springmvc等框架封装到了一起,帮助你隐藏这些框架的细节,实现敏捷开发。springboot就是一个工具集,用来简化spring的搭建和开发过程的。
-
spring的搭建和开发过程
- 各种jar包准备
- jar包缺失、jar包版本冲突
- spring配置,扫描bean
- spring整合mybatis框架,配置数据源、事务等
- 以上两步一般放在一个配置文件中
- springmvc配置,自动扫描controller、视图解析器等等
- web.xml配置,spring容器监听器、编码过滤器、SpringMVC核心控制器等
- …
- 项目部署到服务器,发布运行
- 各种jar包准备
-
存在的困扰
- 真正开发中,jar包不需要开发人员管理
- 配置文件的编写,大部分都是照抄照搬没有什么技术含量,这一块可以自动实现
- 项目的部署和发布依赖第三方容器,相对频繁,可以简化
-
SpringBoot环境搭建
-
前提:必须有Spring开发经验,熟悉maven,熟悉idea
-
创建maven项目(非web项目,纯maven项目)
-
引入依赖
-
创建启动类(主程序),必须放在一个自定义的包下,否则项目无法启动
@SpringBootApplication public class SpringBoot01Application { public static void main(String[] args) { SpringApplication.run(SpringBoot01Application.class); } }
-
创建HelloController
* @RestController :这是@Controller 和 @ResponseBody的组合注解(可以穿透查看), * 如果一个类中的所有方法返回值都不是跳转页面,可以在改类上面添加该注解, * 这样方法上就可以不用添加@ResponseBody注解了 * */ @RestController public class HelloController { /* @GetMapping(""):作用和@RequestMapping一样,只是用来接收get请求 @PostMapping(""):作用和@RequestMapping一样,只是用来接收post请求 */ @GetMapping("/hello") public String hello(){ return "Hello SpringBoot!"; } }
-
运行主程序,启动项目
- 项目没有web部署,也没有整合tomcat,但是启动信息中会看到tomcat启动,说明springboot内置服务器,也就是tomcat
-
访问:localhost:80800/hello
-
-
springboot优势
- spring技术栈的一个大整合,简化spring开发
- 简化搭建过程,依赖帮助我们自动完成
- 简化配置,底层采用默认配置帮我们完成web开发
- 简化部署,springboot内置web容器,也就是tomcat
-
注解
- @RestController
- 这是@Controller 和 @ResponseBody的组合注解(可以穿透查看),如果一个类中的所有方法返回值都不是跳转页面,可以在这个类上面添加该注解,这样方法上就可以不用添加@ResponseBody注解了
- @GetMapping(“”):作用和@RequestMapping一样,只是用来接收get请求
- @PostMapping(“”):作用和@RequestMapping一样,只是用来接收post请求
- @RestController
三、SpringBoot之POM文件解析
- parent标签
- 点击artifactid穿透,发现parent项目又继承了一个parent(spring-boot-dependencies),继续穿透artifactid,在properties标签中可以看到约定了当前springboot版本匹配的第三方技术的jar包以及版本
- 作用
- 管理springboot项目中的依赖版本
- 是的我们导入的依赖不再需要自己指定版本
- 不再springboot管理范围内的jar包需要自己指定版本
- spring-boot-starter-web依赖
- 点击artifactid穿透,发现其中的dependencies中有tomcat相关依赖,json数据绑定相关的依赖,springmvc依赖等,可见springboot将web开发作成了一个场景,继承了我们以往在web开发需要的依赖,并帮助我们管理
- spring-boot-stater
- 是springboot的场景启动器
- 带stater关键字都称为springboot的场景启动器,或起步依赖
- 启动器:springboot会把常用的开发场景所需要的jar包都集成为一个模块,提供给开发人员,把这个场景启动器引入进来,开发这个场景所需的依赖就都被引入进来了
四、主程序解析
-
@SpringBootApplication:SpringBoot的核心注解
-
SpringBoot项目一般都会有一个*Application.java的入口类,入口类中有main方法,这是一个标准的java程序入口方法
-
该注解是一个组合注解
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
-
这三个注解作用和@SpringBootApplication 一样,即springboot提供的统一的注解来替代以上三个注解,简化程序配置
-
作用:从三个注解身上可以看到,配置、自动加载配置、实例化spring容器并实例化和启动类同包以及子包下的bean
-
-
@SpringBootConfiguration:配置类的注解,是springboot提供的注解,标注在类上,表示这是springboot的配置类
-
查看源码,这个注解类@Configuration注解,@Configuration是spring提供的注解,这两个注解功能完全一样,真正启动的不是主程序,而是一个容器,里面加载了所有的配置
-
Spring3.x之后,通过注解@Configuration替代之前的XML配置文件,等价与之前的标签
-
被注解类中包含一个或多个被@Bean注解的方法,@Bean注解在方法上,相当于标签
-
案例
/* 相当于在xml文件中创建了一个beans 标签: <beans></beans> */ @Configuration public class EmpConfig { /* @Bean:相当于 <bean id = "emp" class="com.jxd.model.Emp"> @Bean如果要添加@value属性,以value属性值为对象名,即id值 如果没有添加value 属性,以方法名为对象名,即id值 */ @Bean(value = "emp2") public Emp emp(){ Emp emp = new Emp(); emp.setEmpno(1); emp.setEname("刘备"); emp.setJob("经理"); return emp; } }
@RestController public class EmpController { @Autowired private Emp emp; @GetMapping("/getEmp") public Emp getEmp(){ return emp; } }
-
作用:
- @SpringBootConfiguration 和 @Configuration 作用一样,只不过前者是SpringBoot提供的注解,后者是spring提供的注解,用起来是一样的,都是用来替代XML配置文件的,简化以往繁琐的配置
-
-
@EnableAutoConfiguration
-
注解在类上
-
自动配置是springboot的核心功能,springboot的默认配置以及我们自己写的配置类是如何加载到内存中生效的呢?就是靠这个注解
-
查看源码
@AutoConfigurationPackage //自动配置包 @Import //为spring容器导入其他组件
-
@EnableAutoConfiguration可以帮助springboot应用 将所有符合条件的@Configuration 配置都加载到spring容器中
-
这个注解还告诉springb根据添加的jar包猜测你想如何配置你的spring,由于spring-boot-starter-web中继承了tomcat依赖和springmvc依赖,所以自动配置会假定你正在开发一个web应用,并相应的对spring进行配置,帮助你构建完整的底层web‘支持
-
作用:
- 以前我们需要配置的东西,现在springboot帮助我们配置
- 将主配置类(被SpringBootApplication注解的类)所在包以及其子包下的所有组件扫描到spring容器中
-
-
@ComponentScan
-
标注在类上
-
作用:springboot 是一个依赖注入的框架,所有的内容都是关羽bean及其依赖关系,定义spring beans的第一步是正确的使用注解@Controller,@Service,@Repository,@Component 。但是spring不知道你定义了其他bean,除非你告诉它去哪里找到这些注解。
-
@ComponentScan 就是将注解的位置告诉spring
-
也就是说如果你在启动类所在包或其子包下定义了某个bean,那么你什么都不用做,springboot会帮助你自动扫描的
-
如果创建的bean不在启动类所在包及其子包下,可以在启动类上添加注解,指明要扫描的包
@ComponentScan(basePackages = "com")
-
五、springboot的优势
- SpringBoot致力于简洁,让开发者写更少的配置,程序能够更快的运行和启动
- springboot的核心思想就是约定大于配置,一切由内定的约束自动完成
- springboot 可以简化开发模式,节省配置过程所花费的事件,通过少量代码就可以完成一个应用创建
- springboot是整合了框架的框架
六、快速创建SpringBoot项目
- 创建项目,选择Spring Initializr, 点击next (这一步必须联网)
- 添加项目描述,点击next
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b8O8L8RB-1664250618957)(SpringBoot.assets/image-20220808173057146.png)]
- 选择springboot项目的版本及所需的依赖 (依赖可以不选,后面添加也可以),点击next
- 点击finish,等待依赖下载完成
- 查看目录结构,删除无用文件
- 修改pom.xml中的依赖,找到下面的依赖spring-boot-starter ,在artifactid中添加 -web, 修改为spring-boot-stater-web,因为你要创建的是web项目
- 写业务代码,创建controller
- 启动项目,浏览器访问
七、热部署
- 热部署:就是在程序的运行过程中谢盖代码,却不需要手动重启应用
- 步骤
- 添加依赖
- 添加插件
- 开启自动配置
- file - settings-Build-complier-勾选build project automically
- 同时按住:crtl + shift + alr + / 选择Registry,勾选compiler.automake.allow.when.app.running
- 修改启动配置:Edit Configurations
- on “update“ action : update classes and resources
- on freame deactivation:update classes and resources
- 重启应用,热部署生效
- 修改代码,测试热部署是否生效,如果热部署没有生效,可以点击Build下的Build project
- 热部署原理
- 热部署中有两个类启动器
- baseclassloader:加载不会变化的类,比如第三方的jar包
- restarterclassloader:加载变化的类,在类路径(classpath)下的类
- 在热部署时,base类启动器不会重新加载,而restarter 类启动类会被废弃,有新的restarter类启动类代替加载变化的类,所以速度上看起来比重启要快
- 热部署中有两个类启动器
八、springboot配置文件
-
springboot的默认配置
- springboot自动配置jar包[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iVJRvyAf-1664250618959)(SpringBoot.assets/QQ图片20220809101922.png)]
-
为什么需要配置文件
- springboot是一个约定大于配置的框架,约定好了一些默认值,约定的配置项多于我们自己的个性化配置
- 我们的项目会有一些特殊需求,比如修改端口号、配置数据源等,springboot提供的默认值满足不了我们的个性化需求,这是我们要写配置文件
- 我们需要通过配置文件将配置信息告诉springboot
- 通过挖掘源码可以看到配置文件的路径在src/main/resources下,可以创建的配置文件类型有:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VLqDxqGJ-1664250618960)(SpringBoot.assets/QQ图片20220809102138.png)]
- 三类文件优先级从上往下越来越高,我们主要学习yml类型,yml和yaml语法一致
-
YAML(轻骑兵V8中采用的方式)
-
YAML是一种标记语言,这个语言是通用的,java、c、c++都可以识别该语言
-
它内部是一个属性结构展示配置项,同配置项下的同缩进
-
yaml语法:
#修改服务端口号 server: port: 8082 servlet: #修改应用的根路径 context-path: /demo
- key:value 冒号和value之间有一个空格
- 大小写敏感
- 使用#作为注释,yaml中只有行注释
- 通过这种方式就可以覆盖springboot的默认配置项
-
优点:
- yml文件会根据换行和缩进帮助我们管理配置项的位置
- .yml文件比.properties文件更轻量一些
-
缺点:
- 要更严格遵循换行和缩进
- 在填写value时,一定要在冒号后,value前添加一个空格
-
-
在配置文件中自定义配置项
#定义简单数据配置项 name: 张三 #定义对象 student: id: 1 name: 李明 age: 18 #定义数组 -代表是一个对象 emps: - empno: 1 name: 刘备 age: 20 - empno: 2 name: 关羽 age: 22
-
在业务代码中,获取配置项
-
方式一
@RestController public class ConfigController { /* @Value注解的名称要和配置项中的key 一一对应 该方式适合配置项较少时单个获取 */ @Value("${name}") private String name; @Value("${student.name}") private String stuName; //获取数组中第二个个员工的姓名 @Value("${emps[1].name}") private String ename; @RequestMapping("/getNames") public String getNames(){ return name + "-" + stuName + "-" + ename; } }
-
方式二
/* 如果在配置文件中 需要编写大量的自定义配置项,并且具有统一的前缀, 可以采用如下方式,该方式适用于批量获取配置项 @ConfigurationProperties:这个注解可以根据前缀自动寻找你要获取的配置项, 同时把具体的值映射到属性身上,属性名要和配置项的key相同,同时属性要提供get和set方法 */ @ConfigurationProperties(prefix = "student") @RestController public class StudentController { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @RequestMapping("/getStudent") public String getStudent(){ return id + "-" + name + "-" + age; } }
-
九、springboot整合mybatis
- 项目springboot03
-
数据库中创建表 emp
-
添加依赖
-
在application.yml中配置数据源
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/gcy?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowMultiQueries=true username: root password: root
-
创建实体类Emp
-
创建dao接口IEmpDao,编写方法
-
在启动类上添加注解,扫描dao接口所在的包
@SpringBootApplication @MapperScan(basePackages = "com.jxd.dao")//扫描dao接口所在的包 public class Springboot03Application { public static void main(String[] args) { SpringApplication.run(Springboot03Application.class, args); } }
-
创建mapper映射文件,编写sql
-
在application.yml中进行mybatis的相关设置
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/gcy?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowMultiQueries=true username: root password: root mybatis: #映射文件位置 mapper-locations: classpath:com/jxd/dao/mapping/*.xml #别名设置,在映射文件中只需要写实体类的名称即可(不需要写全限定名称了) type-aliases-package: com.jxd.model #驼峰映射,比如实体类user的属性名userName 和 数据库中的user表中的字段user_name 对应 configuration: map-underscore-to-camel-case: true #在控制台查看sql语句 logging: level: com.jxd.dao: DEBUG
-
编写service层
-
编写controller层
-
启动项目,测试
十、springboot plus
- 项目springboot04
注解
-
@RestController
-
@GetMapping
-
@PostMapping
/* * @RestController :这是@Controller 和 @ResponseBody的组合注解(可以穿透查看), * 如果一个类中的所有方法返回值都不是跳转页面,可以在改类上面添加该注解, * 这样方法上就可以不用添加@ResponseBody注解了 * */ @RestController public class HelloController { /* @GetMapping(""):作用和@RequestMapping一样,只是用来接收get请求 @PostMapping(""):作用和@RequestMapping一样,只是用来接收post请求 */ @GetMapping("/hello") public String hello(){ return "Hello SpringBoot!"; } }