链接:https://pan.baidu.com/s/1quiC-bqO5s3KgoLT5MWX7Q?pwd=412p
提取码:412p
1.Springboot入门
springboot-简化了开发-比如-我们之前导入依赖--到需要自己写配置类-返回Bean
springboot 帮我们简化了这个工程
SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想
spring 缺点 1.配置繁琐 2.依赖繁琐
springboot -1.自动配置 2.起步依赖 3.辅助功能
再起步依赖中导入了很多依赖 这使得我们不需要一个个找版本
//引导类
@SpringBootApplication
public class ItemApplication {
public static void main(String[] args) {
SpringApplication.run(ItemApplication.class, args);
}
}
2.起步依赖分析
1.继承父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
⚫ 在spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本。
2.导入起步依赖
<dependencies>
<!--web开发的起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
在各种starter中,定义了完成该功能需要的坐标合集,其中大部分版本信息来自于父工程。 ⚫ 我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在 版本冲突等问题。
->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
->追到底-最后继承的父pom
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.8.RELEASE</version>
<packaging>pom</packaging>
-这里面规范了大量的依赖版本
3.配置文件读取
1.配置文件了解
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用 application.properties或者application.yml(application.yaml)进行配置。
properties: server.port=8080
yml: server: port: 8080
在同一级目录下优先级为:properties > yml > yaml
2.yaml
yaml-是一种数据序列化格式-知识的它具有丰富的跨平台性
对比
![420f1f189299beef2d6b83fd89aea2e9](G:\360MoveData\Users\nixg\Documents\Tencent Files\2583181473\nt_qq\nt_data\Pic\2024-04\Ori\420f1f189299beef2d6b83fd89aea2e9.png)
语法
![12f41b7bed6805dd726a730295af95c3](G:\360MoveData\Users\nixg\Documents\Tencent Files\2583181473\nt_qq\nt_data\Pic\2024-04\Ori\12f41b7bed6805dd726a730295af95c3.png)
![e5554d0928c36cb20902c0cc1e30017b](G:\360MoveData\Users\nixg\Documents\Tencent Files\2583181473\nt_qq\nt_data\Pic\2024-04\Ori\e5554d0928c36cb20902c0cc1e30017b.png)
![a0698b803cd925e2e094f38a2f2be6e8](G:\360MoveData\Users\nixg\Documents\Tencent Files\2583181473\nt_qq\nt_data\Pic\2024-04\Ori\a0698b803cd925e2e094f38a2f2be6e8.png)
![63d0fdcc32b52981fab07613eae525f1](G:\360MoveData\Users\nixg\Documents\Tencent Files\2583181473\nt_qq\nt_data\Pic\2024-04\Ori\63d0fdcc32b52981fab07613eae525f1.png)
3.读取配置文件内容
1.读取大类
@Value
Environment
@ConfigurationProperties
2.profile
多配置文件切换-比如我们生产环境-每一套生产环境有对应的配置文件
配置方式
profile配置方式 ⚫
多profile文件方式:提供多个配置文件,每个代表一种环境。
• application-dev.properties/yml 开发环境
• application-test.properties/yml 测试环境 •
application-pro.properties/yml 生产环境
激活方式
⚫ 配置文件: 再配置文件中配置:spring.profiles.active=dev
⚫ 虚拟机参数:在VM options 指定:-Dspring.profiles.active=dev
⚫ 命令行参数:java –jar xxx.jar --spring.profiles.active=dev
3.内部加载顺序
Springboot程序启动时,会从以下位置加载配置文件:
- file:./config/:当前项目下的/config目录下
-
- file:./ :当前项目的根目录
-
- classpath:/config/:classpath的/config目录
-
- classpath:/ :classpath的根目录 加载顺序为上文的排列顺序,高优先级配置的属性会生效
加载顺序为上文的排列顺序,高优先级配置的属性会生
Spring-整合框架
1.Spring 整合junit
1.导入依赖-springboot 工程
2.编写测试类
3.添加注解
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJunitApplication.class )
public class UserServiceTest {
@Test
public void test(){
System.out.println(111);
}
}
2.Spring 整合redis
① 搭建SpringBoot工程
② 引入redis起步依赖
③ 配置redis相关属性
④ 注入RedisTemplate模板
⑤ 编写测试方法,测试
redis-键值存储
@Test
public void testSet() {
//存入数据
redisTemplate.boundValueOps("name").set("zhangsan");
}
@Test
public void testGet() {
//获取数据
Object name = redisTemplate.boundValueOps("name").get();
System.out.println(name);
}
---
redisTemplate
----
public BoundValueOperations<K, V> boundValueOps(K key) {
void set(V var1);
return new DefaultBoundValueOperations(key, this);
}
---
3.spring 整合myBatis
@Mapper
@Repository
public interface UserMapper {
@Select("select * from t_user")
public List<User> findAll();
}
放入依赖mapper-哦、配置文件放入配置
搭建SpringBoot工程
② 引入mybatis起步依赖,添加mysql驱动
③ 编写DataSource和MyBatis相关配置
④ 定义表和实体类
⑤ 编写dao和mapper文件/纯注解开发
⑥ 测试
Spring boot高级
1.Spring 启动流程
![SpringBoot启动流程](G:\360MoveData\Users\nixg\Desktop\MAVEN SPRING\PDF\SpringBoot启动流程.png)
2.Spring自动配置
1.Condition
Condition 是在Spring 4.0 增加的条件判断功能,通过这个可以功能可以实现选择性的创建 Bean 操作。
SpringBoot是如何知道要创建哪个Bean的?比如SpringBoot是如 何知道要创建RedisTemplate的
--
2.@Enable*注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注 解导入一些配置类,实现Bean的动态加载。
3.Import注解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用 法:
① 导入Bean
② 导入配置类
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类
④ 导入 ImportBeanDefinitionRegistrar 实现类。
4.@EnableAutoConfiguration
@EnableAutoConfiguration 注解内部使用 @Import(AutoConfigurationImportSelector.class)来加载配置类。 ⚫ 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载 这些配置类,初始化Bean
⚫ 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean
3.Springboot监听机制
Java 监听机制 SpringBoot 的监听机制,其实是对Java提供的事件监听机制的封装。 Java中的事件监听机制定义了以下几个角色:
① 事件:Event,继承 java.util.EventObject 类的对象
② 事件源:Source ,任意对象Object
③ 监听器:Listener,实现 java.util.EventListener 接口 的对
SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成 一些操作。 ApplicationContextInitializer、SpringApplicationRunListener、CommandLineRunner、ApplicationRunner
1.Springboot自动装配
1.开始
概述 :某些对象自动存入IOC容器
例子
比如:配置类GsonAutoConfiguration里面有一个bean,bean的名字叫gson,它的类型是Gson。 ->专门用来处理json数据
@SpringBootTest
class ProgramApplicationTests {
@Autowired
private Gson gson;
@Test
void mmm()
{
String json = gson.toJson(Result.success());
System.out.println(json);
}
}
此处 我们没有手动将该gson对象放入ioc容器 但他确可以拿出来 这就是spring在启动时候 就完成了bean对象的创建
其实分析自动配置原理就是来解析在SpringBoot项目中,在引入依赖之后是如何将依赖jar包当中所定义的配置类以及bean加载到SpringIOC容器中的。
2.自写自动装配
javen jar包
`@Component
public class TokenParser {
`
@Component
public class TokenParser {
public void parse(){
System.out.println("TokenParser ... parse ...");
}
}
@Autowired
private ApplicationContext applicationContext;
@Test
public void testTokenParse(){ System.out.println(applicationContext.getBean(TokenParser.class));
}
`
报错 表示容器内没有找到这个bean
- 原因在我们之前讲解IOC的时候有提到过,在类上添加@Component注解来声明bean对象时,还需要保证@Component注解能被Spring的组件扫描到。
- SpringBoot项目中的@SpringBootApplication注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。
- 当前包:com.itheima, 第三方依赖中提供的包:com.example(扫描不到)
解决方法
- 方案1:@ComponentScan 组件扫描
- 方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中
方案一 指定扫描
@ComponentScan({"com.example.program","com.example"})
但是每一个依赖包都要指定对应目录 太过麻烦 对此 进行方案2
@Import导入
1.普通类
@Import(TokenParser.class) 自己加入bean容器
2.配置类
@Configuration
public class HeaderConfig {
@Bean
public HeaderParser headerParser(){
return new HeaderParser();
}
@Bean
public HeaderGenerator headerGenerator(){
return new HeaderGenerator();
}
}
启动类--放到任意地方都行的
@Import(HeaderConfig.class) //导入配置类
扫描到Bean 自动注册 其他地方就可以拿取该bean
3.使用@Import导入ImportSelector接口实现类:
@Import(MyImportSelector.class)
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.example.HeaderConfig"};//返回全类名
}
}
那两个 对象也会被加入进对应容器
你所提供的代码是Spring中ImportSelector接口的一个实现。ImportSelector接口是Spring的@Import注解处理的一部分,它允许我们动态加载(或导入)一些Spring的配置。
MyImportSelector类实现ImportSelector接口的selectImports方法,这个方法的作用是返回一个包含希望Spring加载的类全限定名称的字符串数组。
在你的例子中,selectImports方法返回一个字符串数组,包含一个元素"com.example.HeaderConfig"。这表示Spring会尝试将com.example.HeaderConfig这个类加载到Spring的应用上下文中。
如图-三种方法都可以进行依赖注入
如果基于以上方式完成自动配置,当要引入一个第三方依赖时,是不是还要知道第三方依赖中有哪些配置类和哪些Bean对象?
思考:当我们要使用第三方依赖,依赖中到底有哪些bean和配置类,谁最清楚?
- 答案:第三方依赖自身最清楚。
结论:我们不用自己指定要导入哪些bean对象和配置类了,让第三方依赖它自己来指定。‘’
怎么让第三方依赖自己指定bean对象和配置类?
- 比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以@EnableXxxx开头的注解,注解中封装的就是@Import注解
使用第三方依赖提供的 @EnableXxxxx注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类
public @interface EnableHeaderConfig {
}
前两个注解详解
@Retention: 这个注解决定了被修饰的注解信息在什么级别可用。
RetentionPolicy.SOURCE:注解只保留在源码中,编译时会被丢弃,不会写入字节码。
RetentionPolicy.CLASS:注解在编译时被保留在字节码中,但JVM加载类时不会将其加载到反射数据中,这是默认的生命周期。
RetentionPolicy.RUNTIME:注解在编译后也会被保存在字节码中,JVM加载类时将其加载到反射数据中,所以它们能在运行时被读取到。
因此,@Retention(RetentionPolicy.RUNTIME)意味着被修饰的注解在运行时仍然有效,可以通过反射机制读取到。
@Target: 这个注解用来指定被修饰的注解可以用在哪些元素上。元素类型包括:CONSTRUCTOR(构造器声明),FIELD(字段声明),LOCAL_VARIABLE(局部变量声明),METHOD(方法声明),PACKAGE(包声明),PARAMETER(参数声明), TYPE(类、接口或枚举声明)等。
所以,@Target(ElementType.TYPE)表示被修饰的注解只能用来修饰类、接口或枚举。
以上四种方式都可以完成导入操作,但是第4种方式会更方便更优雅,而这种方式也是SpringBoot当中所采用的方式。
@SpringBootApplication
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
@Target({ElementType.TYPE}) 该注解意味着@SpringBootApplication只能用于类、接口或枚举类型。
@Retention(RetentionPolicy.RUNTIME) 表示@SpringBootApplication注解会被保留在运行时,因此可以通过反射获取其信息。
@Documented 表明如果一个类使用了@SpringBootApplication注解,那么这个注解应该被包含在JavaDoc中。
@Inherited 表示@SpringBootApplication注解可以被子类继承。//配置类
@SpringBootConfiguration //起步依赖--通过 @SpringBootApplication 注解启动时,Spring Boot 会自动扫描并加载所有 @SpringBootConfiguration 注解的配置类,并根据配置类中的内容进行自动装配,从而实现对应用的自动配置和启动。
@EnableAutoConfiguration启动Spring Boot的自动配置机制。
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)使Spring Boot能够扫描当前类所在的包以及子包,查找Component,Configuration等。
如上-跟踪自动装配的依赖
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage// 这是一个Spring Boot的内部注解,用于自动配置包扫描路径。Spring Boot将从声明@EnableAutoConfiguration的类的包开始,向下扫描包结构。
@Import({AutoConfigurationImportSelector.class})
AutoConfigurationImportSelector.class
在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports配置文件中指定了第三方依赖Gson的配置类:GsonAutoConfiguration
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
//第一个参数又这个给
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
//配置导入
AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
//第一个参数
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
/// AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
-----------autoConfigurationMetadata
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
-->load方法
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties");
}
在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports配置文件中指定了第三方依赖Gson的配置类:GsonAutoConfiguration
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
---这就是要加入ioc容器的类
这么多 不会累坏吗 spring怎么知道哪些要加入哪些不加入呢
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration
@Configuration//表面该类是自动配置类
@ConditionalOnClass({Gson.class})//类的是否创建 类在类路径生效才生效--在spirng中-要存在配置才导入
@EnableConfigurationProperties({GsonProperties.class})
public class GsonAutoConfiguration {
public GsonAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean//条件注解 这意味着只有当Spring容器中不存在类型为Gson 的Bean时,该方法返回的实例才会被注册为Bean
public Gson gson(GsonBuilder gsonBuilder) {
return gsonBuilder.create();
}
}
条件注解详解
@Configuration
public class HeaderConfig {
@Bean
@ConditionalOnClass(name="io.jsonwebtoken.Jwts")//环境中存在指定的这个类,才会将该bean加入IOC容器
public HeaderParser headerParser(){
return new HeaderParser();
}
//省略其他代码...
理就是在配置类中定义一个@Bean标识的方法,而Spring会自动调用配置类中使用@Bean标识的方法,并把方法的返回值注册到IOC容器中。
@ConditionalOnMissingBean //不存在该类型的bean,才会将该bean加入IOC容器
@ConditionalOnMissingBean(name="deptController2")//不存在指定名称的bean,才会将该bean加入IOC容器
@ConditionalOnMissingBean(HeaderConfig.class)//不存在指定类型的bean,才会将bean加入IOC容器
@ConditionalOnProperty(name ="name",havingValue = "itheima")//配置文件中存在指定属性名与值,才会将bean加入IOC容器
总结-从启动类依赖开始找->自动装配依赖->自动装配依赖类的依赖->这个依赖的参数_>selectImport函数->配置代码
@SpringBootApplication->@EnableAutoConfiguration->@Import({AutoConfigurationImportSelector.class})->AutoConfigurationImportSelector->
->selectImport->
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
这个过程就是spirng-boot-再启动的时候->会依据配置文件 去读取加载的Bean
bean中又包含了条件创建bean的结构
@Bean
@ConditionalOnMissingBean//条件注解 这意味着只有当Spring容器中不存在类型为Gson 的Bean时,该方法返回的实例才会被注册为Bean
public Gson gson(GsonBuilder gsonBuilder) {
return gsonBuilder.create();
}