聊聊SpringBoot自动装配的魔力

目录
  • 一、 springBoot自动配置的好处
    • 1、 回想一下当你在使用spring来搭建一个项目的时候
    • 2、这时我们会有一个疑问
  • 二、@Conditional注解相关介绍
    • 1、@Conditional小demo
  • 三、自定义一个条件配置类/springBoot自定义注解
    • 1、简单解释@Condition注解家族
    • 2、自定义条件注解

一、 springBoot自动配置的好处

1、 回想一下当你在使用spring来搭建一个项目的时候

你需要编写很多的有关spring的xml。例如读取属性配置的bean、数据源bean、事务管理工厂bean、mybatis与spring整个的bean等等。再次利用该框架搭建项目的时候,又是周而复始的操作。

但是现在当你使用springBoot搭建项目的时候,你会发现所有的配置你都不用去编写就可以帮你去实现(仅仅需要在连接外部数据库的时候需要进行配置,其实如果使用内嵌数据库h2 则你完全不必需要application.properties配置文件)。

你可以在你的具体的业务代码中使用@AutoWried @Resource注解将数据源,事务工厂等注入到业务层,像是你自己配置那样。

2、这时我们会有一个疑问

springBoot到底做了什么让我们可以不用配置,而使用那些功能对象。

其实springBoot使用基于条件的自动注入原理,即为当满足某个条件的时候,spring会实例化该注解对应的bean,将其放入到Srping上下文中,让你可以轻松的使用。SpringBoot实现条件配置离不开它的核心组件@Conditional。

下面我们慢慢的来揭开springBoot自动配置的神秘面纱。

二、@Conditional注解相关介绍

1、@Conditional小demo

@Conditional 是个什么鬼,不解释来个小的demo大致了解一下

描述一下demo场景 :Life实体bean在特定条件(@Conditional)下,被springBoot初始化,并放置到spring上下文环境中。

1.1、 Life 实体类

/**
 * 梦想存在,生命才有意义
 */
public class Life {
    //工作
    private String work;
    //学习
    private String study
    //爱
    private String love;

  //省略seter /geter

}

1.2、 编写我们自己的条件匹配规则

/**
 * 实现ConfigurationCondition(该接口继承了Condition)
 */
public class MyTestConditional implements ConfigurationCondition {
    /**
     * 设置使用该类进行解析的时机
     * 1、REGISTER_BEAN:会在注册Bean的时候进行condition的解析
     *  即为在对应的@Bean注解和@condition注解组合使用的时候 进行条件的判断
     *  @Bean注解对应spring 的xml的<bean/>标签
     * 2、PARSE_CONFIGURATION:会在解析@Configuration时进行condition的解析
     *    即为在对应的@Configuration注解和@condition注解组合使用的时候 进行条件的判断
     *    @Configuration注解对应spring 的xml的<beans/>标签
     * @return
     */
    @Override
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.REGISTER_BEAN;
    }
    /**
     * 该方法为条件判断的核心 只有该方法返回为true 则表示其条件成立 ,执行相应的配置
     * @param conditionContext
     * @param annotatedTypeMetadata
     * @return
     */
    @Override
    public boolean matches(ConditionContext conditionContext,
    AnnotatedTypeMetadata annotatedTypeMetadata) {
              return false;  //表示验证不通过
    }

该类实现了ConfigurationCondition 有如下两个方法

1、 getConfigurationPhase() 该条件规则起作用的时候

2、 matches()条件匹配规则 这里为了演示不做具体的逻辑条件的处理

返回一个布尔值,如果为ture 则表示条件成立 配置生效

反之不生效。

1.3、编写我们的java实例bean自动配置

@Configuration
//@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,
// 作用为:配置spring容器(应用上下文)
public class ServerAutoConfiguration {

    @Configuration  //spring的xml配置文件中的<beans>
    //使用该注解表明,在springBoot启动的时候只有满足MyTestConditional.class 才生成对应的Life 对象
    //即 MyTestConditional中的match()返回true @Bean生效
    @Conditional(MyTestConditional.class)
    public static class StudentAutoConfiguration {
        @Bean
        public Life create() {
            System.out.println("life start....");
            return new Life("努力工作","不断的学习","敢爱敢恨");
        }
    }
}

1.4、 springBoot的单元测试


//使用Spring的单元测试环境
@RunWith(SpringRunner.class)
//将SpringBoot的上下文环境加载进入单元测试中
@SpringBootTest(classes = AutoApplication.class)
public class AutoApplicationTests {
   //注入springBoot 基于条件的实例化bean
   @Autowired
   private Life life;
   @Test
   public void showlife() {
      System.out.println("生命的全部:"+life.toString());
   }
}

启动springBoot项目,在控制台中没有发现Life对象被创建 且单元测试中无法注入Life

在修改了MyTestConditional中的match() 返回true 再次启动则Life对象被创建

同时使用SpringBoot的单元测试来使用springBoot为我们设置的Life实体

该实体创建流程如下:当springBoot项目启动的时候,会加载@Configuration(srping的xml配置)下的所有bean,当遇到@Conditional(MyTestConditional.class) 会调用该方法的Match,并根据其返回值来判断是否实例化该注解下的所有使用@Bean @Import 注解下的类

三、自定义一个条件配置类/springBoot自定义注解

1、简单解释@Condition注解家族

(1)、@Conditional

官方文档定义:

“Indicates that a component is only eligible for registration when all specified conditions match”

意思是只有满足一些列条件之后创建一个bean。 并注册到spring的上下文环境中

(2)、SpringBoot提供的

  • @ConditionalOnWebApplication 该应用必须为web应用
  • @ConditionalOnMissingBean 该应用上下文中如果没有指定的bean
  • @ConditionalOnBean 该应用上下文中如果有指定的bean
  • @ConditionalOnProperty(name,value) 只有存在对应name的value的配置文件才加载该注解下的bean
  • @ConditionalOnCloudPlatform 匹配当处于云平台环境中时后
  • @ConditionalOnClass 该classpath中如果有指定的bean @ConditionalOnExpression 如果对应的表达式成立 成功
  • @ConditionalOnJava 根据应用程序运行的JVM版本进行匹配 成功
  • @ConditionalOnRepositoryType 当特定类型的spring Data JPA启用的时候 成功
  • @ConditionalOnSingleCandidate 当特定的class对应的bean存在且唯一确定的时候
  • @ConditionalOnJndi 通过JNDI查找制定的条件
  • @Profile 通过特定的条件触发 (生产环境使用该配置,非生产环境则不是使用)
  • @ConditionalOnResource 从资源文件中查询
  • @ConditionalOnEnabledResourceChain 从资源链中中查询
  • @ConditionalOnNotWebApplication 如果改应用不是web应用,则该条件起作用
  • @ConditionalOnMissingClass 如果不存在对应的class则创建该对应的bean

满足条件后则加载该注解作用下的类起作用

(3)、所谓该注解作用下的类起作用是指

这些注解都有如下两种使用方式

1、作用在类上,则该类下的所有@Bean注解起作用 (条件成立,加载该注解下的所有@Bean的实体类 存放在spring上下文中)

2、作用在方法上 则该方法下对应的@bean注解起作用 (条件成立,加载该注解下使用@Bean的实体类 存放在spring上下文中)

与@Configuration或者@Bean配合使用,当和@Configuration配合使用时,

那么该类下所有@Bean方法 或者@Import 或者 @ComponentScan都会受到其配置条件的影响

  • @Configuration 相当于spring的xml配置文件的<beans>标签
  • @Bean 注解相当于spring的xml配置文件的<bean>标签
  • @Import(Xxx.class)将指定的class 实例注入到spring的上下文中
  • @Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,作用为:配置spring容器(应用上下文)

2、自定义条件注解

结合demo 来设置一个自定义注解

(1)、 自定义注解

/*
  自定义的Conditional 条件注解
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyTestConditional.class)
public @interface ConditionalOnLife {
    Class<?>[] value() default {};
    String[] name() default {};}

(2)、进行配置使用

@Configuration  //spring的xml配置文件中的<beans>
//使用该注解表明,在springBoot启动的时候只有满足MyTestConditional.class 才生成对应的Life 对象
//自定义的条件注解
@ConditionalOnLife
//@Conditional(MyTestConditional.class)
public static class DreamAutoConfiguration {
    @Bean
    public Dream createDream() {
        //life.toString();
        System.out.println("dream start....");
        return new Dream();
    }
}

后台调用成功创建了Dream实体 并放入spring上下文环境中

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java Springboot自动装配原理详解

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

  • springboot自动装配的源码与流程图

    前言 在使用SpringBoot开发项目中,遇到一些 XXX-XXX-starter,例如mybatis-plus-boot-starter,这些包总是能够自动进行配置, 减少了开发人员配置一些项目配置的时间,让开发者拥有更多的时间用于开发的任务上面.下面从源码开始. 正文 SpringBoot版本:2.5.3 从@SpringBootApplication进入@EnableAutoConfiguration 然后进入AutoConfigurationImportSelector @Target

  • 手把手带你分析SpringBoot自动装配完成了Ribbon哪些核心操作

    目录 一.项目案例准备 1.Order服务 2.User服务 二.Ribbon原理分析 1.RibbonAutoConfiguration 2.LoadBalancerAutoConfiguration 总结 一.项目案例准备 首先我们大家案例环境,通过[RestTemplate]来实现服务调用,通过[Ribbon]实现客户端负载均衡操作. 1.Order服务 我们的Order服务作为服务提供者.创建SpringBoot项目,并添加相关依赖 <?xml version="1.0"

  • SpringBoot自动装配Condition的实现方式

    目录 1. 简介 2. 定义 2.1 @Conditional 2.2 Condition 3. 使用说明 3.1 创建项目 3.2 测试 3.3 小结 4. 改进 4.1 创建注解 4.2 修改UserCondition 5. Spring内置条件注解 1. 简介 @Conditional注解在Spring4.0中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean. 2. 定义 2.1 @Conditional @Conditional注解定义如下:其内部只有一个参数

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

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

  • 聊聊SpringBoot自动装配的魔力

    目录 一. springBoot自动配置的好处 1. 回想一下当你在使用spring来搭建一个项目的时候 2.这时我们会有一个疑问 二.@Conditional注解相关介绍 1.@Conditional小demo 三.自定义一个条件配置类/springBoot自定义注解 1.简单解释@Condition注解家族 2.自定义条件注解 一. springBoot自动配置的好处 1. 回想一下当你在使用spring来搭建一个项目的时候 你需要编写很多的有关spring的xml.例如读取属性配置的bea

  • 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自动装配原理初识

    运行原理 为了研究,我们正常从父项目的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自动装配原理小结

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

  • 浅析SpringBoot自动装配的实现

    目录 背景 解析 起始 具体解析 结论 备注 背景 众所周知,如下即可启动一个最简单的Spring应用.查看@SpringBootApplication注解的源码,发现这个注解上有一个重要的注解@EnableAutoConfiguration,而这个注解就是SpringBoot实现自动装配的基础 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.Spri

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

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

随机推荐