SpringBoot自动装配原理小结

约定优于配置(Convention Over Configuration)是一种软件设计范式,目的在于减少配置的数量或者降低理解难度,从而提升开发效率。

先总结一下结论:

springboot通过spring.factories能把main方法所在类路径以外的bean自动加载,其目的就是为了帮助自动配置bean,减轻配置量

springboot autoconfig的一些实验

一个springboot工程,springbootautoconfig.test.config这个包和启动类的包不再同一个路径下,那么这个包下的注解等应该不会生效,bean也无法托管给spring管理

@Configuration//开启配置
@EnableConfigurationProperties(HelloProperties.class)//开启使用映射实体对象
@ConditionalOnClass(TestHello.class)//存在TestHello时初始化该配置类
@ConditionalOnProperty//存在对应配置信息时初始化该配置类
(
        prefix = "zxp.hello",//存在配置前缀zxp.hello
        value = "flag"
)
public class HelloAutoConfiguration {
    @Autowired
    private HelloProperties helloProperties;

    @Bean//创建HelloService实体bean
    @ConditionalOnMissingBean(TestHello.class)//缺失HelloService实体bean时,初始化HelloService并添加到SpringIoc
    public TestHello helloService()
    {
        System.out.println(">>>The TestHello Not Found,Execute Create New Bean.");
        TestHello testHello = new TestHello(helloProperties.getName(),helloProperties.getFlag());
        return testHello;
    }
}
@ConfigurationProperties(prefix = "zxp.hello")
@Data
public class HelloProperties {
    private String name;
    private String flag;
}
public class TestHello {
    String name;
    String flag;

    public TestHello(String name, String flag) {
        this.name = name;
        this.flag = flag;
    }

    public String print(){
        String msg = "name is "+name + "  " + "flag is "+flag;
        System.out.println(msg);
        return msg;
    }
}

在resources下创建META-INF路径,并创建spring.factories文件

#配置自定义Starter的自动化配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=springbootautoconfig.test.config.HelloAutoConfiguration

再试启动又报错了

- Bean method 'helloService' not loaded because @ConditionalOnProperty (zxp.hello) did not find property 'flag'

原因是,如果没有配置zxp.hello.flag,怎会报错

@ConditionalOnProperty//存在对应配置信息时初始化该配置类
(
        prefix = "zxp.hello",//存在配置前缀hello
        value = "flag"//开启
)

在application.properties中添加

zxp.hello.flag=2

成功了,访问controller

name is null flag is 1

SpringBoot autoconfig部分注解说明

@ConditionalOnXxx 可以根据条件来决定是否执行自动配置

@ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件

@ConditionalOnClass:当SpringIoc容器内存在指定Class的条件
@ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnProperty:指定的属性是否有指定的值

@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnWebApplication:当前项目是Web项目的条件

@AutoConfigureBefore
@AutoConfigureAfter
@AutoConfigureOrder
public @interface ConditionalOnProperty {
    String[] value() default {}; //数组,获取对应property名称的值,与name不可同时使用
    String prefix() default "";//property名称的前缀,可有可无
    String[] name() default {};//数组,property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用
    String havingValue() default "";//可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
    boolean matchIfMissing() default false;//缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错
    boolean relaxedNames() default true;//是否可以松散匹配,至今不知道怎么使用的
}

SpringBoot autoconfig原理

springboot启动类注解@SpringBootApplication引入@EnableAutoConfiguration又引入@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector类中调用SpringFactoriesLoader.loadFactoryNames 方法扫描了所有JAR包的META-INF/spring.factories,如下代码:

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
         getBeanClassLoader());
   Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
         + "are using a custom packaging, make sure that file is correct.");
   return configurations;
}
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    ……
    Enumeration<URL> urls = (classLoader != null ?
      classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
      ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
    result = new LinkedMultiValueMap<>();
    while (urls.hasMoreElements()) {

spring-boot-autoconfigure包内的spring.factories文件内容

……
work.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
……

包含了所有spring为其增加的自动配置的bean配置,这些bean在满足条件后会被加载到spring上下文中,从而实现了自动配置

eg:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ RabbitTemplate.class, Channel.class })
@EnableConfigurationProperties(RabbitProperties.class)
@Import(RabbitAnnotationDrivenConfiguration.class)
public class RabbitAutoConfiguration {

会发现RabbitTemplate会报错,为什么这里不存在的类却不报错呢? 1、这个jar编译时这个类是有的,保证编译能过 2、看下ConditionalOnClass注解的注释

The classes that must be present. Since this annotation is parsed by loading class bytecode, > it is safe to specify classes here that may ultimately not be on the classpath, only if this annotation is directly on the affected component and not if this annotation is used as a composed, meta-annotation. In order to use this annotation as a meta-annotation, only use the name attribute. Returns: the classes that must be present

必须出现的类。由于此注释是通过加载类字节码来解析的,因此在此处指定最终可能不在类路径上的类是安全的,前提是此注释直接位于受影响的组件上,而不是将此注释用作组合的元注释。要将此注释用作元注释,请仅使用name属性。

starter

starter就是整理了依赖的maven配置,主要指maven相关依赖配置到单独的一个工程以避免引入过多的maven配置

以上就是SpringBoot自动装配原理详解的详细内容,更多关于SpringBoot自动装配原理的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot自动装配原理详解

    首先对于一个SpringBoot工程来说,最明显的标志的就是 @SpringBootApplication它标记了这是一个SpringBoot工程,所以今天的 SpringBoot自动装配原理也就是从它开始说起. 自动装配流程 首先我们来看下@SpringBootApplication 这个注解的背后又有什么玄机呢,我们按下 ctrl + 鼠标左键,轻轻的点一下,此时见证奇迹的时刻.. 我们看到如下优雅的代码: 这其中有两个比较容易引起我们注意的地方,一个是@SpringBootConfigur

  • 浅谈springboot自动装配原理

    一.SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFi

  • springboot如何实现自动装配源码解读

    Spring Boot 自动装配 最重要的注解@SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, c

  • SpringBoot自动装配原理小结

    约定优于配置(Convention Over Configuration)是一种软件设计范式,目的在于减少配置的数量或者降低理解难度,从而提升开发效率. 先总结一下结论: springboot通过spring.factories能把main方法所在类路径以外的bean自动加载,其目的就是为了帮助自动配置bean,减轻配置量 springboot autoconfig的一些实验 一个springboot工程,springbootautoconfig.test.config这个包和启动类的包不再同一

  • springboot自动装配原理初识

    运行原理 为了研究,我们正常从父项目的pom.xml开始进行研究. pom.xml 父依赖 spring-boot-starter-parent主要用来管理项目的资源过滤和插件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE<

  • SpringBoot启动及自动装配原理过程详解

    一.servlet2(老spring-mvc) 配置文件: web.xml:主要配置项目启动项 application-context.xml:主要配置项目包扫描.各种bean.事务管理 springMVC.xml:主要配置controller包扫描.视图解析器.参数解析器 启动过程: 每一个spring项目启动时都需要初始化spring-context,对于非web项目可以在程序main方法中触发这个context的初始化过程. 由于web项目的启动入口在容器,所以开发者不能直接触发sprin

  • Springboot自动装配实现过程代码实例

    创建一个简单的项目: <?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/PO

  • 深入浅析SpringBoot中的自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提.这次主要的议题是,来看看它是怎么样实现的,我们透过源代码来把握自动装配的来龙去脉. 一.自动装配过程分析 1.1.关于@SpringBootApplication 我们在编写SpringBoot项目时,@SpringBootApplication是最常见的注解了,我们可以看一下源代码: /* * Copyright 2012-2017 the original author or authors. * * Licensed un

  • Java SpringBoot自动装配原理详解及源码注释

    目录 一.pom.xml文件 1.父依赖 2.启动器: 二.主程序: 剖析源码注解: 三.结论: 一.pom.xml文件 1.父依赖 主要是依赖一个父项目,管理项目的资源过滤以及插件! 资源过滤已经配置好了,无需再自己配置 在pom.xml中有个父依赖:spring-boot-dependencies是SpringBoot的版本控制中心! 因为有这些版本仓库,我们在写或者引入一些springboot依赖的时候,不需要指定版本! 2.启动器: 启动器也就是Springboot的启动场景; 比如sp

  • 深入了解Java SpringBoot自动装配原理

    目录 自动装配原理 SpringBootApplication EnableAutoConfiguration AutoConfigurationImportSelector 总结 在使用springboot时,很多配置我们都没有做,都是springboot在帮我们完成,这很大一部分归功于springboot自动装配,那springboot的自动装配的原理是怎么实现的呢? 自动装配原理 springboot 版本:2.4.3 SpringBootApplication springboot启动类

  • Java Springboot自动装配原理详解

    目录 Debug路线图 让我们从run说起 归属 小结 run 再说说注解 总结 Debug路线图 说多都是泪,大家看图. 让我们从run说起 用了这么多年的的Springboot,这个 run() 方法到底做了些什么事呢? @SpringBootApplication public class SpringbootDemoApplication { public static void main(String[] args) { SpringApplication.run(Springboot

  • 最新springboot中必须要了解的自动装配原理

    目录 1.pom.xml 2.启动器 3.主程序 3.1注解 3.2 spring.factories 4. 结论 1.pom.xml 父 依 赖 \textcolor{orange}{父依赖} 父依赖 spring-boot-dependencies:核心依赖都在父工程中 这里ctrl+左键,点击之后我们可以看到父依赖 这个里面主要是管理项目的资源过滤及插件,我们发现他还有一个父依赖 看看下面这个,熟悉吗? 再点进去,我们发现有很多的依赖.这就是SpringBoot的版本控制中心. 这个地方才

  • SpringBoot详细分析自动装配原理并实现starter

    目录 约定优于配置 自动装配 手写一个starter组件 约定优于配置 SpringBoot的预定优于配置主要体现在以下几个方面: maven的目录结构: 配置文件默认存放在resources目录下 项目编译后的文件存放在target目录下 项目默认打包成jar格式 配置文件默认为application.yml或application.yaml或application.properties 默认通过 spring.profiles.active 属性来决定运行环境时的配置文件. 自动装配 相对于

  • SpringBoot 自动装配的原理详解分析

    目录 前言 自动装配案例 自动装配分析 自动装配总结 前言 关于 ​​SpringBoot​​​ 的自动装配功能,相信是每一个 ​​Java​​ 程序员天天都会用到的一个功能,但是它究竟是如何实现的呢?今天阿粉来带大家看一下. 自动装配案例 首先我们通过一个案例来看一下自动装配的效果,创建一个 ​​SpringBoot​​ 的项目,在 ​​pom​​ 文件中加入下面的依赖. <dependency> <groupId>org.springframework.boot</gro

随机推荐