SpringBoor入门
1.简介
- SpringBoot 来建华Spring应用开发,约定大于配置,去繁从简,just run就能创建一个独立的,产品级别的应用,简化Spring应用开发的一个框架,整个Spring技术栈的一大整合,J2EE开发的一站式解决方案
背景
- J2EE笨重的开发,众多的配置,底下的开发效率,复杂的部署流程,第三方技术集成难度大
解决
- Spring全家桶时代,SpringBoot-》J2EE一站式解决方案‘
- SpringCloud-》分布式整体解决答案
2.微服务(架构风格)
单体运用:ALL-IN-ONE
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YBo8rqOB-1602768509024)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201014173315.png)]
微服务:
- 一个应用应该是一组小型服务,可以通过HTTP进行交互
- 每一个功能元素最终形成的都是可独立替换和独立升级的软件单元
- 详细参考文档:https://martinfowler.com/microservices/
3.SpringBoot HelloWorld
一个功能:
浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串
1.创建一个maven工程
2.导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>SpringBoot_Study</groupId>
<artifactId>Spring-boot-01-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Spring-boot-01-helloworld</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.编写主程序:启动SpringBoot
package Helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author lenovo
* 开启SpringBoot的第一个项目
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
//Spring应用启动起来
ConfigurableApplicationContext run = SpringApplication.run(HelloWorldApplication.class, args);
}
}
4.编写controller
**注意:**controller要和SpringBoot启动文件在一个目录,否则扫描不到controller
package Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author lenovo
*/
@Controller
public class HelloController {
@ResponseBody
@RequestMapping()
public String hello(){
return "Hello World";
}
}
5.测试结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7UausOLz-1602768509027)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201014184054.png)]
6.简化部署工作
<!--这个插件,可以将以你的引用打包成一个可执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
将这个应用达成jar包,直接使用java -jar的命令进行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIV3zDKX-1602768509029)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201014190000.png)]
7.Hello World探究
1.Pom文件
1.父项目
spring-boot-starter-parent:场景启动器的父类,也是来给启动器版本号的
<groupId>SpringBoot_Study</groupId>
<artifactId>Spring-boot-01-helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<!--将Spring-boot-starter-parent作为父项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--点进去父类pom文件可以看出来,所有的依赖的版本是由这个父类来管理的
这个父类spring-boot-starter-parent可以说是SpringBoot的版本仲裁中心
SpringBoot的版本仲裁中心,以后我们导入依赖不需要版本号的,当然,没有在dependencies里面管理的依赖,必须声明版本号
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
spring-boot-starter-parent可以说是SpringBoot的版本仲裁中心,以后我们导入依赖不需要版本号的,当然,没有在dependencies里面管理的依赖,必须声明版本号
父类的pom文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q24GsuJL-1602768509031)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201014191052164.png)]
2.启动器
- 导入的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
spring-boot-starter-web可以分为两个模块:
- 1.spring-boot-starte:场景启动器,帮我们导入web模块正常运行所依赖的组件
- 2.web表示对应模块
- 加在一起就是表示,让启动器加入web模块的依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nQujhXeX-1602768509035)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201014192236846.png)]
当你想要不同的功能,你可以去官网查找并导入不同的启动器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gXq9WgE9-1602768509036)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201014192537.png)]
2.结论
- Spring将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些这些starter相关场景的所有依赖都会导入进来,要什么 功能就导入什么场景的启动器
2.主程序类,主入口类
package Helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author lenovo
* 开启SpringBoot的第一个项目
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
//Spring应用启动起来
ConfigurableApplicationContext run = SpringApplication.run(HelloWorldApplication.class, args);
}
}
**@SpringBootApplication:**SpringBoot应用标注在某个类上,说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.repository.Repository;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
**@SpringBootConfiguration:**SpringBoot配置类
标记在某个类上,表示这是一个Spring Boot的配置类
**@Configuration:**Spring的注解,告诉当前的类为配置类,配置类上标注这个注解
配置类-------配置及文件
**@Component:**表示配置类(被@Configuration修饰的类)也是一个
**@EnableAutoConfiguration:**开启自动配置功能
以前我们需要配置的东西,SpringBoot帮我们自动配置,@EnableAutoConfiguration:告诉SpringBoot自动配置功能,这样自动配置才能生效
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
**@AutoConfigurationPackage:**自动配置包
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
**@Import(AutoConfigurationPackages.Registrar.class):**Spring底层注解@import,作用是给容器导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class
将当前主配置类(SpringBoot)所在的包下的所以的组件扫描进Spring容器中
源码调试结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FGyu851H-1602768509037)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201014211824.png)]
举个例子:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OISnfRmW-1602768509038)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201014211429898.png)]
这样的就不行了,因为扫描的包是Helloworld.Test
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mw4zc70X-1602768509040)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201014211604001.png)]
这样就可以了,因为现在扫描包是Helloworld
@EnableAutoConfiguration注解下还有一个:@Import(AutoConfigurationImportSelector.class),表示导入组件,告诉EnableAutoConfiguration导入组件AutoConfigurationImportSelector(导入那些组件的选择器),
AutoConfigurationImportSelector将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中,他会给容器导入非常多的自动配置类(xxxxautoConfiguration)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bbAKOagG-1602768509042)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201015182453301.png)]
那么如何来判断来扫描这些类呢
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yjbx2ogz-1602768509043)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201015191524358.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CxrhLocu-1602768509045)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201015191630997.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pISDuqok-1602768509046)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201015192316.png)]
从类路径下的META-INF/Spring.factorys中获取 EanbelAutoConfiguratin指定的值,将这些作为自动配置类导入到容器中,自动配置类就生效,帮我们自动进行配置工作
J2EE的整体整合解决方案和自动配置都在SpringBoot-autoconfigure-1.5.9RELEASE.jar
7. 使用Spring Initializer快速创建SpringBoot项目
IDE都支持Sprnng的项目创建向导快速创建一个Spring Boot项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JRJCyjPs-1602768509048)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201015195121.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M8w15l7M-1602768509051)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201015195131.png)]
导入模块
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YIv1JyXi-1602768509052)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201015195250.png)]
创建成功:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bvhMLg65-1602768509054)(https://raw.githubusercontent.com/Codemilk/LearnNotes/main/Pic/20201015203053.png)]
写入Handler
这里提一下:@@RestController:就是@ResponseBody和@controller
package springbootinitializerquick.springbootinitializer.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lenovo
*
*@RestController 就是@controller和@Response的集合
* RestController类的代码头:
* @Target(ElementType.TYPE)
* @Retention(RetentionPolicy.RUNTIME)
* @Documented
* @Controller
* @ResponseBody
* public @interface RestController {
*
*/
@RestController
public class RestHandler {
@RequestMapping("/hello")
public String test(){
return "hello world";
}
}
运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Am1demG-1602768509055)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201015202606078.png)]
总结:
默认生成的Spring Boot项目:
- 选择我们需要的模块,向导会联网创建Spring Boot
- resources文件夹中目录结构
- static:保存所有的静态资源:js css images
- templates:保存所有的模板页面;SpringBoot默认jar包使用嵌入式的Tomcat,默认不支持jsp的!!!!!!!!,但我们可以使用模板引擎(freemarker,thymeleaf)
- application.properties:Spring Boot应用的配置文件,可以在里面配置服务器端口号等属性
如:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qd6rK2Uv-1602768509055)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20201015203619125.png)]
SpirngBoot配置
1.配置文件
- application.properties
- application.yml
配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们配好了
Yaml(YAML Ain’t Markup language)
YAML A Markup Language:yaml是一个标记语言
YAML isn’t Markup Language:yaml是一个标记语言
标记语言:
以前的配置文件;大多都是用的是.xml
Yaml:以数据为重心,比JSON,XML等更适合做配置文件