Web day11 SpringBoot原理

目录

1.配置优先级:

2.Bean的管理:

bean的作用域:

第三方bean:

方案一:

方案二:

SpringBoot原理:

扫描第三方包:

[方案1:@ComponentScan 组件扫描](#方案1:@ComponentScan 组件扫描)

[方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)](#方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中))

1). 使用@Import导入普通类:. 使用@Import导入普通类:)

2). 使用@Import导入配置类:. 使用@Import导入配置类:)

3). 使用@Import导入ImportSelector接口实现类:. 使用@Import导入ImportSelector接口实现类:)

4). 使用第三方依赖提供的 @EnableXxxxx注解. 使用第三方依赖提供的 @EnableXxxxx注解)

自定义启动器starter:

[1.自定义 aliyun-oos-spring-boot-starter 模块(起步依赖)](#1.自定义 aliyun-oos-spring-boot-starter 模块(起步依赖))

[2.创建aliyun-oss-spring-boot-autoconfigure 自动配置模块](#2.创建aliyun-oss-spring-boot-autoconfigure 自动配置模块)


1.配置优先级:

在我们前面的课程当中,我们已经讲解了SpringBoot项目当中支持的三类配置文件:

  • application.properties

  • application.yml

  • application.yaml

配置文件优先级排名(从高到低):

  1. properties配置文件

  2. yml配置文件

  3. yaml配置文件

五种配置方式的优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数

2.Bean的管理:

bean的作用域:

在前面我们提到的IOC容器当中,默认bean对象是单例的 (只有一个实例对象)。在Spring中支持五种作用域,后三种在web环境才生效:

  • 可以借助Spring中的@Scope注解来进行配置作用域
java 复制代码
//默认bean的作用域为:singleton (单例)
@RestController
@RequestMapping("/depts")
public class DeptController {

    @Autowired
    private DeptService deptService;

    public DeptController(){
        System.out.println("DeptController constructor ....");
    }

    //省略其他代码...
}

测试类:

java 复制代码
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {

    @Autowired
    private ApplicationContext applicationContext; //IOC容器对象

    //bean的作用域
    @Test
    public void testScope(){
        for (int i = 0; i < 10; i++) {
            DeptController deptController = applicationContext.getBean(DeptController.class);
            System.out.println(deptController);
        }
    }
}

ApplicationContext applicationContext; //为IOC容器对象 可以拿到IOC 容器中的bean对象

重启SpringBoot服务,运行测试方法,查看控制台打印的日志:

可以看到bean的作用域默认singleton 单例 容器中只会有一个bean对象

  • 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时) 在第一次使用时才会创建bean对象

第三方bean:

在我们项目开发当中,当这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的,那么此时我们是无法使用 @Component 及其衍生注解来声明bean的,此时就需要使用**@Bean**注解来声明bean 了。

因为第三方的类无法加@Component 被 spring项目扫描(默认只扫描启动类所在的包及其子包)

把第三方类对象放入 IOC容器:

方案一:

在启动类定义方法 返回的对象就会自动变为bean对象**(切入到启动类不建议)**

方案二:

1.在类上定义 @Configuration 注解

2.在方法上加入@Bean注解 返回的对象会自动变成bean对象

单独在conf包下定义配置类

  • 通过@Bean注解的name 或 value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。

  • 如果第三方bean需要依赖其他bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。

SpringBoot原理:

SpringBoot框架之所以使用起来更简单更快捷,是因为SpringBoot框架底层提供了两个非常重要的功能:一个是起步依赖 ,一个是自动配置

起步依赖:

springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当中,就集成了web开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。

自动配置:

SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

我们在我们整个项目中,也并未配置Gson这个类型的bean,为什么可以直接注入使用呢? 原因就是因为这个bean,springboot中已经帮我们自动配置完毕了,我们是可以直接使用的。

扫描第三方包:

如果 不在启动类所在的包及其子包的 包中的类也想被 IOC 容器 管理 @bean只针对一个对象

扫描别的包可以把别的包中@Component 类交给IOC管理

方案1:@ComponentScan 组件扫描

java 复制代码
@SpringBootApplication
@ComponentScan({"com.itheima","com.example"}) //指定要扫描的包
public class SpringbootWebConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfigApplication.class, args);
    }
}

在启动类加入@ComponentScan 注解可以自动扫描 别的包中的@Component注解加入IOC容器

我们进行项目开发时,当需要引入大量的第三方的依赖,就需要在启动类上配置N多要扫描的包,这种方式会很繁琐。而且这种大面积的扫描性能也比较低。

缺点:

  1. 使用繁琐

  2. 性能低

结论:SpringBoot中并没有采用以上这种方案。

方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)

  • 入形式主要有以下几种:

    • 导入普通类

    • 导入配置类

    • 导入ImportSelector接口实现类

首先要把想要使用模块的 依赖 导入到spring项目模块中 才能找到对应的包

1). 使用@Import导入普通类:

java 复制代码
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfigApplication.class, args);
    }
}

不用写@Component注解 类对象会被直接导入

2). 使用@Import导入配置类:

用配置类可以把多个bean对象一次放入IOC容器中

配置类:

启动类:

导入配置类IOC容器中会有 配置类对象 和 配置类中的两个bean对象

3). 使用@Import导入ImportSelector接口实现类:

ImportSelector接口实现类

java 复制代码
public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //返回值字符串数组(数组中封装了全限定名称的类)
        return new String[]{"com.example.HeaderConfig"};
    }
}

启动类

java 复制代码
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class, args);
    }
}

以上三种方法 都i需要在启动类自己@Import 类 但是我们一般并不清楚 第三方类的名字

  • 比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以@EnableXxxx开头的注解,注解中封装的就是@Import注解

4). 使用第三方依赖提供的 @EnableXxxxx注解

  • 第三方依赖中提供的注解
java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类
public @interface EnableHeaderConfig { 
}
  • 在使用时只需在启动类上加上@EnableXxxxx注解即可
java 复制代码
@EnableHeaderConfig  //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebConfig2Application.class, args);
    }
}

自动配置原理源码入口就是 @SpringBootApplication 注解,在这个注解中封装了3个注解,分别是:

  • @SpringBootConfiguration

    • 声明当前类是一个配置类
  • @ComponentScan

    • 进行组件扫描(SpringBoot中默认扫描的是启动类所在的当前包及其子包)
  • @EnableAutoConfiguration

封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)

在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-

  • INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。

    • 封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)

当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器中,交给IOC容器管理。

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中定义的配置类非常多,而且每个配置类中又可以定义很多的bean,那这些bean都会注册到Spring的IOC容器中吗?

答案:并不是。 在声明bean对象时,上面有加一个以 @Conditional 开头的注解,这种注解的作用就是按照条件进行装配,只有满足条件之后,才会将bean注册到Spring的IOC容器中(下面会详细来讲解)

自定义启动器starter:

目的:将阿里云util 文件上传类对象 自动放到 IOC 容器中 可以直接注入使用

否则 在 不同项目中都需要重新写util类

只需要引入启动器依赖即可

springboot的启动器 默认会 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

文件中的配置类 并把配置类 中的 bean 对象加载到IOC容器中

我们只需要定义相同的路径 把我们 自己的配置类放到 .imports 文件中即可

·

1.自定义 aliyun-oos-spring-boot-starter 模块(起步依赖)

只需要有pom 文件即可

在pom 文件中 只需要引入 自动配置模块的依赖

2.创建aliyun-oss-spring-boot-autoconfigure 自动配置模块

EnableAutoConfigureAliyunOSS为util 的配置类

java 复制代码
@Configuration // 声明为配置类:实现自动配置
public class EnableAutoConfigureAliyunOSS {

    // 把阿里云的OSS文件上传对象交给spring容器管理。
    // 阿里云对象需要配置信息对象的
    // 阿里云的属性对象可以注入给文件上传对象。
    @Bean
    public OSSFileUpholdUtil ossFileUploadUtil() {
        return new OSSFileUpholdUtil();
    }
}

在 .import 文件中写入 配置类的路径 springboot自动配置时就会自动添加bean

相关推荐
fs哆哆1 小时前
ExcelVBA判断用户选择区域是否整行或整列
java·开发语言·前端·javascript·ecmascript
phenomenal992 小时前
微服务-01【续】
java·微服务·架构
LG.YDX3 小时前
计算机组成原理课后习题答案:第一章
java·开发语言
ssxueyi4 小时前
Java 常见Exception异常解决方法
java·开发语言·数据库·异常处理·exception
xzq_java4 小时前
Javafx.麦当劳点餐系统(Java简洁版)
java·sql
silver6874 小时前
jvm内存优化
java
lzz的编码时刻4 小时前
观察者模式:事件处理机制与松耦合设计
java·开发语言·设计模式
yun_shui_4 小时前
【力扣-KMP】28.找出字符串第一个匹配项的下标
java·数据结构·算法·leetcode
lvyuanj5 小时前
IDEA skywalking 启动报错 ClassNotFoundException InstanceConstructorInterceptor
java·intellij-idea·skywalking