首页 > 其他分享 >springboot为什么要用延迟导入?

springboot为什么要用延迟导入?

时间:2024-05-04 18:22:46浏览次数:11  
标签:EnableRegisterServer springboot Bean 导入 注解 class 延迟

Spring Boot使用了多种方式来实现自动配置,其中DeferredImportSelector接口是这些机制之一。

DeferredImportSelectorImportSelector的一个扩展,它允许延迟导入配置类直到所有@Configuration类都被处理完毕。这对于某些自动配置类需要在应用程序上下文的创建过程中的后期阶段才能做出决定的场景很有用。

为什么这么说呢?因为springboot导入的自动装配类大多都有@Conditional注解来判断这个装配类所依赖的类在当前路径下存不存在,@Conditional有很多种,有的只需要判断当前项目路径下有没有该类(比如:@ConditionalOnClass,有的需要判断当前spring容器中有没有该类的Bean比如:(@ConditionalOnBean)。

所以,当情况为后者时,使用@Conditional注解时必须确保我们导入的Bean已经存在了。所以就会延迟导入。那些加在启动类上的@EnableXXX注解就是这样的,在注解内部会用@Import导入一个标记类的Bean,然后再在自动装配类上@ConditionalOnBean注解判断有没有该Bean。这样就可以用@EnableXXX注解来控制是否导入自动装配类

下面我们分别举例:

举例1、

我举一个第一种情况的例子,假如我们项目中要用到Mybatis,那我们要导入mybatis的依赖和mybatis-spring-boot的依赖。当然,这两个依赖被springboot整合了

在mybatis-springboot的依赖中就会有一个自动装配类:MybatisAutoConfiguration

@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration implements InitializingBean {

@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class }) 的意思就是当类路径下存在SqlSessionFactorySqlSessionFactoryBean这两个类时,配置才会被激活,相应的Bean才会被创建。只要存在即可,不需要让他成为容器的Bean。因为这两个类都是mybatis包下的,我们总不能在这两个类上加一个@Component注解吧!所以只需要判断存在即可。所以只要我们导入了mybatis的依赖,这个判断就会生效。

举例2

这个例子就是我们自定义starter

新增一个标记类ConfigMarker

public class ConfigMarker{
    
}

新增@EnableRegisterServer注解,利用@Import注解导入ConfigMarker到Bean容器

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({ConfigMarker.class}) //将ConfigMarker添加到容器中
public @interface EnableRegisterServer{
    
}

改造HttpAutoConfiguration,新增条件注解@ConditionalOnBean(Marker.class)

@Configuration
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnBean(Marker.class) //只有当Marker类的Bean在容器中存在时,当前自动配置类才会生效
public class HttpAutoConfiguration {

    @Resource
    private HttpProperties properties; // 使用配置

    // 在Spring上下文中创建一个对象
    @Bean
    public HttpClient init() {
        HttpClient client = new HttpClient();

        String url = properties.getUrl();
        client.setUrl(url);
        return client;
    }

}

测试一下,在另外一个springboot项目中导入当前工程starter,在主启动类上添加注解@EnableRegisterServer

大功告成。

如果不在主启动类上添加@EnableRegisterServer注解,当前的标注类Marker就不会被导入。就不会满足@ConditionalOnBean(Marker.class)注解的条件,HttpAutoConfiguration自动配置类也就不会被导入了。

这时候再使用:

 @Resource
    private HttpClient httpClient;

程序就会报错,因为spring容器中根本就不存在这个这个Bean。

所以,就通过@EnableRegisterServer注解给自动装配提供了一个开关。

标签:EnableRegisterServer,springboot,Bean,导入,注解,class,延迟
From: https://www.cnblogs.com/xxiaot/p/18172539

相关文章

  • CMakeLists.txt --- 导入接口库(预编译库)
    以接口库的方式导入预编译库cmake_minimum_required(VERSION3.9)project(test)set(CMAKE_BUILD_TYPEDebug)set(CMAKE_C_FLAGS"$ENV{CFLAGS}-O2-Wall-pthread")set(CMAKE_CXX_FLAGS"$ENV{CFLAGS}-O2-Wall-pthread-std=c++11-std=gnu++11")#设置mo......
  • Unity导出场景并导入Godot
    使用FBXExporter导出场景FBX创建ExportScene.cs导出场景OBJ(目的是创建碰撞体),代码:点击查看代码/******************************************//**//*Copyright(c)2018monitor1394*//*https://github.com/monito......
  • 解决创建SpringBoot工程加载较慢的问题
    设置ServerURL将https://start.spring.io改为https://start.aliyun.com如图所示:启动演示如图所示,启动成功......
  • SpringBoot3.1.5对应新版本SpringCloud开发(1)-Eureka注册中心
    服务的提供者和消费者服务之间可以通过Spring提供的RestTemplate来进行http请求去请求另一个Springboot的项目,这就叫做服务间的远程调用。当一个服务通过远程调用去调用另一个服务时,被调用的服务就叫做服务的提供者,调用服务的服务就叫做服务的消费者。一个服务可以既是服务的提......
  • springboot+MDCAdapter自定义starter实现日志全链路追踪
    MDCMDC(MappedDiagnosticContext,映射调试上下文)是日志系统提供的一种方便在多线程条件下记录日志的功能使用场景一个常用的场景就是Web服务器中给每个请求都分配一个独特的请求id,所有的日志都会打印这个请求id,这样一个请求下的所有日志信息都可以很方便的找到。欢迎关注个人公......
  • SpringBoot中分页插件PageHelper的使用
    SpringBoot如何使用PageHelper实现分页查询在原始的分页查询方法中,需要编写复杂的SQL语句来限制查询结果的范围,通常需要使用LIMIT或者ROWNUM等数据库特定的语法来实现分页。在每个需要分页的查询方法中,都需要手动计算分页的起始位置和偏移量,通常需要根据页码和每页数量来计算,这部......
  • [springboot]配置文件加载顺序
    一般项目直接使用.jar文件以server.port配置举例;以jar包内和jar包外说明内部和外部配置文件顺序由高到底,如下:外部-启动时指定参数外部-环境变量外部config/yml文件外部yml文件内部config/yml文件内部yml文件启动时,如果指定了激活的profile文件,会优先找激活的profile文......
  • [springboot] application.yml是变灰色的,不支持输入提示
       检查是否存在插件:springbootassistant,springbootFile->Setting; plugins,查看右侧“Installed”不存在则安装springbootassistant默认插件中如果没有找到springbootassistant,安装springassistant插件效果如下,显示为有绿色的图标 内容也支持输入提示......
  • [springboot]一启动就自动停止了
    刚刚新建的springboot项目,启动日志显示成功了,但是服务却自动停了。 一种常见的问题是缺少必要的依赖项:SpringBootWeb添加maven依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.1.7.R......
  • 1. SpringBoot 入门
    1.SpringBoot简介SpringBoot是由Pivotal团队提供的全新框架,可以帮助我们开发基于Spring的、独立的、生产级的应用程序。​其中SpringBoot的官网是:SpringBootReferenceDocumentationSpringBoot的主要目标是:为所有Spring开发提供更快的入门体验开箱即用,提供了自动配......