首页 > 其他分享 >spring boot

spring boot

时间:2024-04-27 12:36:24浏览次数:17  
标签:spring 配置 boot public Spring 注解 class

链接: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程序启动时,会从以下位置加载配置文件:

  1. file:./config/:当前项目下的/config目录下
    1. file:./ :当前项目的根目录
      1. classpath:/config/:classpath的/config目录
        1. 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容器

img

image

总结-从启动类依赖开始找->自动装配依赖->自动装配依赖类的依赖->这个依赖的参数_>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();
}

标签:spring,配置,boot,public,Spring,注解,class
From: https://www.cnblogs.com/Agtw/p/18161903

相关文章

  • 有意思!一个关于 Spring 历史的在线小游戏
    发现SpringOne的官网上有个好玩的彩蛋,分享给大家!进到SpringOne的官网,可以看到右下角有个类似马里奥游戏中的金币图标。点击该金币之后,会打开一个新的页面,进入下面这样一个名为:TheHistoryOfSpring的在线小游戏你可以使用上下左右的方向键来控制Spring的Logo一步步经历......
  • 一个通用的SpringBoot项目响应实体类Response
    packagecom.luky.vo;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importlombok.ToString;importorg.springframework.http.HttpStatus;@Data@ToString@AllArgsConstructor@NoArgsConstructorpublicclassResponse&......
  • SpringBoot+MyBatisPlus报错 Invalid value type for attribute 'factoryBeanObjectTy
    依赖版本org.springframework.boot:spring-boot-starter-web:3.2.5com.baomidou:mybatis-plus-boot-starter:3.5.5错误Invalidvaluetypeforattribute'factoryBeanObjectType'问题原因:这个问题是由于依赖传递导致,在MyBatis起步依赖中的myBatis-spring版本过低,导致程......
  • django自定义构建模板,通过bootstrap实现菜单隐藏和显示
    实现后的界面1.自定义页面模板实现主页面代码(home.html){%extends'layout.html'%}#引用模板{%loadstatic%}{%blockcontent%}<h3>欢迎登录</h3>{%endblock%}自定义内容layout.html文件设置(模板){%loadstatic%}{%loadmenu%}#导入m......
  • spring-接口大全
    1.Bean相关1.InitializingBeanInitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。demo@ComponentpublicclassMyInitBeanimplementsInitializingBean{publicvoidafterPro......
  • springboot链接redis IPV6
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion>......
  • Spring Boot应用中如何动态指定数据库,实现不同用户不同数据库的场景
    当在SpringBoot应用程序中使用SpringDataJPA进行数据库操作时,配置Schema名称是一种常见的做法。然而,在某些情况下,模式名称需要是动态的,可能会在应用程序运行时发生变化。比如:需要做数据隔离的SaaS应用。所以,这篇博文将帮助您解决了在SpringBoot应用程序中如何设置动态S......
  • springBoot源码(一)
    构造函数运行代码publicConfigurableApplicationContextrun(String...args){ Startupstartup=Startup.create(); if(this.registerShutdownHook){ SpringApplication.shutdownHook.enableShutdownHookAddition(); } DefaultBootstrapContextbootstrapConte......
  • SpringSecurity认证授权完整流程
    SpringSecurity认证流程:loadUserByUsername()方法内部实现。实现步骤:   构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。建一个service实现类,实现此loadUserByUsername方法。调用登录的login接口,会经过authenticationManager.authenticate(authent......
  • SpringBoot整合AOP实现打印方法执行时间切面
    pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>代码创建注解importjava.lang.annotation.ElementType;importja......