一般把Spring Boot称为搭建程序的脚手架或者说是便捷搭建基于Spring的工程脚手架。
Spring的主要作用就是帮助开发人员快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,让开发人员更多的关注业务而不是配置。
Spring Boot简化了spring的应用开发
Spring Boot是整个Spring技术栈的大整合
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
//引入此springboot的父项目配置,用于依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<!--此依赖引入之后,springboot会自动将我们整个项目所需要的web相关依赖自动导入-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
/**
* 主程序类
* @SpringBootApplication:这是一个SpringBoot应用
*/
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//这里run方法的第一个参数以这个类的类名加“.class”,第二个参数为main方法的参数列表中的args参数
SpringApplication.run(MainApplication.class,args);
}
}
@RestController
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "Hello, Spring Boot 2!";
}
}
最后我们只需要启动mian方法运行即可
Spring Boot简化了配置,我们不需要再去通过大量的xml文件去配置项目
我们只需要在resource文件下创建一个扩展名为.properties的文件然后将我们需要修改的配置在这个文件内进行重新配置即可
//例如将访问端口改为8888
server.port=8888
在初级的spring开发,我们需要安装Tomcat服务器然后将spring项目打包成war包之后发布到服务器然后再通过游览器去访问
但是在SpringBoot中,SpringBoot为我们提供了一个插件自动将我们的项目打包成一个jar包,为我们创建了一个可执行的jar包,这个jar包内自带了我们整个项目的运行环境,然后我们通过终端执行相应的命令来运行这个jar包即可启动项目
//在pom.xml文件写引入
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
然后我们选中clean和package然后运行,进行打包()
如果打包出错,我们就需要减低springboot的版本或者降低maven-resources版本
降低maven-resources版本为3.1.0
- 注1:如果是通过终端terminal敲命令打包的,请打开一个新的终端terminal
- 注2:如果是通过右侧maven管理窗口打包的,请重启idea
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <!--修改版本--> <version>3.1.0</version> </plugin>
降低springboot版本为2.3.7.RELEASE
注1:如果是通过终端terminal敲命令打包的,请打开一个新的终端terminal
注2:如果是通过右侧maven管理窗口打包的,请重启idea
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.7.RELEASE</version> </parent>
以上这种方式为我们简化了部署
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version></parent>
几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-*</artifactId>
</dependency>
当我们需要的版本号与springboot自动仲裁的版本不一样的时候我们可以修改版本号
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
<!--例如修改mysql驱动版本-->
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
结合@Configuration以及@Bean组件,实现对组件的注册和添加
作用:标注一个配置类
在spring阶段,我们对spring进行配置都是通过xml文件去执行的
但是现在在springboot中,我们不再需要使用xml配置去配置配置spring的容器了,而是直接去创建一个类作为配置类,然后使用@Comfiguration去标注这个类,这个类就相当于一个xml配置文件,我们可以在里面给IoC容器添加bean组件等等。
//标注成一个配置类,告诉SpringBoot这是一个配置类@Configurationpublic class Myconfig { //配置 ......}
使用@Configuration标注的配置类实质上也是容器中的一个组件,也就是说我们也可以通过getBean()来获取这个组件
//获取配置类组件run.getBean(Myconfig.class)
@Configuration的proxyBeanMethods属性
这个属性主要用来配置在我们从容器中获取bean组件的时候是否保持组件的单例性
- 属性值:true或false(默认为true)
- 当为true时:(Full)
- SpringBoot每次都会去检查容器内是否存在我们获取的组件,如果有直接返回,如果没有则新建,但是保持单例性
- 当为false时:(Lite)
- 每次我们获取组件的时候都会新建一个对象返回
对于这个属性值的设置,分为两种模式:
- Full模式:(proxyBeanMethods = true):保证每个@Bean方法被调用多少次返回的组件都是单实例的
- Lite模式:(proxyBeanMethods = false):每个@Bean方法被调用多少次返回的组件都是新创建的
- Full模式由于每次都要去检查组件是否存在,所以运行效率比Lite低
对于这两种模式的使用场景:当我们需要实现组件间依赖的时候就要使用默认的Full模式,反之使用Lite模式
//标注为一个配置类
@Configurationpublic class Myconfig {
//使用@Bean标注,调用方法并将返回的bean添加到IoC容器内。id为“userName”
@Bean("username")
public User user(){
return new User();
}}
@SpringBootApplicationpublic class Application {
public static void main(String[] args) {
//这里的run方法执行之后的除了启动项目之外会返回这个项目的IOC容器
ConfigurableApplicationContext run=SpringApplication.run(Application.class,args);
User user=run.getBean("user",User.class);
System.out.println(user);
}}
在我们项目的任何一个组件类上使用该注解标注,就可以将组件导入到对应的组件类中
该注解的属性类型是一个数组,我们可以将多个组件通过该组件进行导入
该注解会根据我们给定的属性值自动的调用无参构造去给容器创建出对应的组件
//创建User类型的组件和DBhelper类型的组件
@Import({User.class,DBhelper.class})
@Configurationpublic class Myconfig {
//使用@Bean标注,调用方法并将返回的bean添加到IoC容器内。id为“userName”
@Bean("username")
public User user(){
return new User();
}}
该注解的工作原理就是根据条件进行装配,当满足指定条件的时候,该注解下的类内的配置或者方法内的配置才生效
放在配置类上表示,当容器中满足条件时,配置类中的组件才生效;
放在配置方法上的时候,表示的意思是当满足条件的时候配置方法才生效;
下图为@Conditional派生出来的注解,各自的执行原理都有所不同
例如:下面的例子,我们的user方法内部是依赖了tom方法所注册的bean组件,但是由于tom方法没有被@Bean注解,则容器内不会存在有tom方法注册的bean组件,那么在user方法内部对于tom组件的依赖就会存在问题,这时候我们就可以在user上使用@Conditinal注解来对tom是否存在进行判断然后再决定user方法是否生效
@Configurationpublic class myconfig{ //判断id为tom的bean组件是否存在 @ConditionalOnBean(name="tom") @Bean public User user(){ return new User(tom); } //@Bean("tom") -->当这个注解存在的时候tom存在否则不存在 public Tom tom(){ return new Tom(); }}
当我们的项目中有基于spring阶段的xml配置文件同时我们需要把这些文件修改成基于springboot的配置类但是一个一个去重新配置又很麻烦,这时候我们就可以直接在某个配置类上使用该注解将指定的xml配置文件导入到配置类下
例如我们要将spring.xml中的配置迁移到MyConfig配置类下
@Configuration @ImportResource(classpath:"spring.xml") public class MyConfig{ ..... }
为了便于项目的灵活配置以及更好的模块化整合,我们在springboot项目内将大量的参数配置配置在properties文件或者yml文件中,然后我只需要通过@ConfigurationProperties这个注解来获取这些数据即可
注意点:
@Component+@ConfigurationProperties直接在对应类上使用这两个直接将bean组件添加到容器内并进行配置绑定
@EnableConfigurationProperties+@ConfigurationProperties
使用@EnableConfigurationProperties在配置类内指定实现配置绑定的类,开启其配置绑定
在对应的类中使用@ConfigurationProperties实现配置绑定
将bean添加到容器中在进行绑定
@ConfigurationProperties
//properties文件中
//这里定义属性的方式一般都在属性名前加一个前缀用于@ConfigurationProperties通过该前缀确定属性
myuser.name="小明"
//对应的在组件中
@Component
//这里对于该注解的prefix属性,该属性定义了该类内部属性的前缀,用于与properties文件内相互识别
@ConfigurationProperties(prefix = "mycuser")
public class Car {
private String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
/*
如上:properties文件内的myuser.name属性就会于Car下的name实现单向绑定
*/
//通过以上的方式将数据进行绑定之后,该类的bean已经存在于容器内,这样我们可以直接来使用这个bean
@RestController
public class test{
//直接通过注解从容器中获取并自动注入即可
@Autowired
Car car;
@RequestMapping("/car")
public Car car(){
return this.car
}
}
@EnableConfigurationProperties,直接开启注解,直接在配置类中使用并指定某个类,开启这个类的配置绑定,所以不用使用@Componet这些注解去将bean添加到容器内
两个功能:
使用该注解配合
ConfigurableApplicationContext run=SpringApplication.run(Application.class,args
//参数分别为:组件id、组件对于的类类型名.class
run.getBean(BeanId,BeanClassName.class);
boolean beanx=run.containsBean(BeanIdName);
这个插件简化我们的开发,例如在编译的时候自动生成get set方法
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
引入该插件,我们可以直接ctrl+F9就可以重新加载我们的项目,无需我们去手动去点击重新加载
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
通过使用@ControllerAdvice以及@InitBinder结合实现对请求参数的预处理,即在获取到表单中的数据进行绑定到实体的时候先进行一些额外的处理
使用场景
代码实现
//实体A
public class A{
private String name;
//省略set和get方法
}
//实体B
public class B{
private String name;
//省略set和get方法
}
//Controller类下的配置
@RequestMapping('/ab')
//在请求参数前使用@ModelAttribute将参数与@InitBinder标注的预处理方法进行绑定
public String AB(@ModelAttribute("a") A a,@ModelAttribute("b") B b){
return a.getName()+">>"b.getName();
}
//使用@ControllerAdvice定义预处理类以及方法
@ControllerAdivce
public class Controlleradvice{
//指定该方法与@ModelAttribute属性值为a的进行绑定
@InitBinder('a')
public void init1(WebDataBinder binder){
//加上前缀a.
binder.setFieldDefaultPrefix("a.");
}
@InitBinder('b')
public void init1(WebDataBinder binder){
//加上前缀a.
binder.setFieldDefaultPrefix("b.");
}
}
//最后只需要在游览器上输入‘http://localhost:8888?a.name=111&b.name=22’
//这里的演示是在没有前端的情况下为了测试我们自己写好请求参数在url上,如果从前端接收过来的情况下会自动将参数进行绑定
只要将静态资源放在对应的类路径下:
都可以通过静态资源的文件名来访问
**访问:**当前项目根目录/+静态资源名 ---->例如:localhost:8080/xxx.jpg
!!!!!!!!!!!!!!!!!!!!!!
对于静态资源的访问原理:首先请求进来之后先去找Controller看看能不能有没有相应的映射去处理请求,如果有这处理请求返回请求结果;如果没有,则会将请求交给静态资源管理器,静态资源管理器去寻找有没有相应的静态资源,有则返回该静态资源,没有则显示404错误
由于springboot默认的拦截规则是 /** ,这样就会导致与我们的动态资源拦截冲突
所以为了解决这个问题,我们可以在application.properties文件中对静态资源的拦截规则以及静态资源的路径进行配置
#请求拦截规则
spring.mvc.static-path-patten=/static/**
#静态资源路径
spring.mvc.resources.static-locations=classpath:/static/**
以上配置之后,我们就可以通过localhost:8080/static/xxx.jpg 的请求去请求静态资源了**
还可以通过java类进行配置,就是定义一个配置类!
SpringBoot支持两种方式的欢迎页
直接欢迎页的html文件放在静态资源的路径下(static),在不修改默认配置的情况下,访问localhost:8080,springboot 会自动解析index.html文件作为我们的欢迎页
或者将index.html放在我们自己指定的静态资源路径下,通过配置定义我们的静态资源路径,但是这种情况下不能配置静态资源拦截规则
首先我们在编写接口来对请求进行映射的时候,一般都是有一个请求对应一个映射方法
但是现在我们不用那样繁琐的去命名每一个请求路径表示一种请求了
现在我们只需要声明@RequestMapping注解的value以及method属性的值即可实现使用在同一个请求路径下执行不同的请求处理操作
如下:
//f该方法用于处理与/getUser(获取)同样的请求
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
return "GET-张三";
}
//postUser保存
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
return "POST-张三";
}
//putUser修改
@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
return "PUT-张三";
}
//deleteUser删除
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}
这种方式下提交方式要求为post
需配置:
spring.mvc.hiddenmethod.filter.enabled=true #开启页面表单的Rest功能
前端表单:
<form action="/test" method="post">
<input name="_method" type="hidden" value="DELETE">
<input type="submit" value="REST_DELETE" >
</form>
这种方式会先将表单中的DELETE绑定到_method上,然后springboot拦截请求之后寻找对应 _method的请求方法去处理
@PathVariable-----绑定url获取参name数
@RequestMapping("/test1/{id}/{name}")
public Map<String,Object> test1(@PathVariable("id") String id,
@PathVariable("name") String name,
@PathVariable Map<String,String> map
){
Map<String,Object> mapx=new HashMap<>();
mapx.put("id",id);
mapx.put("name",name);
mapx.put("map",map);
return mapx;
}
//接收请求url中id跟name,或者直接接收所有参数
@RequestHeader(“请求头名”) —用于获取请求头
@RequestMapping("/test2")
public Map<String,Object> test2(@RequestHeader("User-Agent") String useragent,
@RequestHeader Map<String,Object> map
){
Map<String,Object> mapx=new HashMap<>();
mapx.put("useragent",useragent);
mapx.put("所有请求头",map);
return mapx;
}
@RequestParam() 获取请求参数
@RequestMapping("/test3")
public Map<String ,Object> test3(@RequestParam("id") String id,
@RequestParam("name") String name,
@RequestParam Map<String,Object> map){
Map<String,Object> mapx=new HashMap<>();
mapx.put("id",id);
mapx.put("name",name);
mapx.put("map",map);
return mapx;
}
CookieValue 获取cookie值
@RequestMapping("/test4/cookie")
//获取Webstorm-58540ded这个cookie的值
public String test4(@CookieValue("Webstorm-58540ded") String cookie){
return "Webstorm-58540ded="+cookie;
}
@RequestBody (获取post方式提交的请求体) 由于post提交不是在url
@PostMapping("/test5")
public String postmathod(@RequestBody String name){
return name;
}
@RequestAttribute ----获取request域中属性,当我们执行页面转发的时候可以从request中拿数据到下一个页面
@GetMapping("/test6")
public String forwardtesst7(HttpServletRequest httpServletRequest){
httpServletRequest.setAttribute("name","由test6转发到test,在test7中获取request");
//转发
return "/test7";
}
@ResponseBody
@GetMapping("/test7")
//从request域中获取name
public Map<String,Object> test7(@RequestAttribute("name") String name,
HttpServletRequest httpServletRequest
){
Map<String,Object> mapx=new HashMap<>();
mapx.put("name1",name);
mapx.put("name2",httpServletRequest.getAttribute("name"));
return mapx;
}
对于map与model,我们只要往map或者model内放数据就相当于调用request.setAttributes(),往request内放参数
重定向携带数据
<form action="/booktestpojo" method="get">
<input type="text" name="name">
<input type="text" name="author">
<input type="submit" value="提交">
</form>
//自动将请求参数封装到对应的实体上
@RequestMapping("/booktestpojo")
public Book book(Book book){
return book;
}
使用@RespouseBody标注将数据响应出去,用于处理异步请求时向前端返回json数据、
@Controller
@RequestMapping("/body")
public class RespouseBodyTest {
@RequestMapping("/user")
@ResponseBody
public User getUser(){
User user=new User();
user.setName("小白");
return user;
}
}