亲手实现一个springboot默认配置&起步加载

Spring Boot 是一个用于快速开发 Spring 应用程序的框架,提供了很多默认配置和起步加载功能,这使得 Spring Boot 应用程序能够更快速地启动和运行。
起步加载是指,Spring Boot 会根据应用程序的依赖关系自动加载所需的类库和配置,从而简化了应用程序的部署和管理。开发者只需要在项目中添加相应的依赖项,Spring Boot 就会自动处理它们之间的依赖关系,并加载所需的类库和配置。

起步加载还可以帮助开发者快速地搭建基于 Spring Boot 的应用程序。Spring Boot 提供了很多起步依赖,这些依赖包含了一些常用的功能,例如 Web 开发、数据库访问、安全认证等。开发者只需要添加相应的起步依赖,就可以快速搭建一个基于 Spring Boot 的应用程序。

Spring Boot自动配置的实现原理主要基于Spring的条件化配置(Conditional Configuration)机制,该机制可以根据特定条件自动配置Spring应用程序的某些部分。

Spring Boot通过在classpath中查找特定的类,来确定应该配置哪些组件。这些类被称为自动配置类(Auto-configuration Classes),它们使用Spring的条件化配置机制来决定是否应该配置特定的组件。当应用程序需要这些组件时,Spring Boot会自动将它们配置好。

Spring Boot自动配置的实现过程如下:

Spring Boot在classpath中查找所有META-INF/spring.factories文件,该文件列出了所有自动配置类。

Spring Boot将这些自动配置类加载到Spring的ApplicationContext中。

自动配置类使用Spring的条件化配置机制来决定是否应该配置特定的组件。

如果条件得到满足,Spring Boot将自动配置类中的Bean定义注册到Spring的ApplicationContext中。

应用程序可以使用这些自动配置的Bean,而无需显式地进行配置。

总的来说,Spring Boot自动配置的实现原理基于Spring的条件化配置机制,它可以根据特定条件自动配置应用程序的某些部分,简化了Spring应用程序的开发过程。

实现

一、默认配置
1、创建springboot项目引入spring-boot-dependencies依赖
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

spring-boot-autoconfigure 是springboot自动配置依赖,springboot提供的默认配置都在这个依赖中

开启自动配置注解:

  • @EnableAutoConfiguration
    • exclude = Class<?>[]
  • @SpringBootApplication (内部包含了@EnableAutoConfiguration)
2、创建配置类
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
//包含GreetingApplicationRunner这个类时才会生效
@ConditionalOnClass(GreetingApplicationRunner.class)
public class GreetingAutoConfiguration {
    @Bean
    //当spring容器中没有GreetingApplicationRunner类时加载
    @ConditionalOnMissingBean(GreetingApplicationRunner.class)
    // greeting.enabled 值等于 true时配置加载;matchIfMissing = true greeting.enabled值为空时也加载
    @ConditionalOnProperty(name = "greeting.enabled", havingValue = "true", matchIfMissing = true)
    public GreetingApplicationRunner greetingApplicationRunner() {
        return new GreetingApplicationRunner();
    }
}
3、在resources目录下创建META-INF/spring.factories 写入:
# 自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
geektime.spring.hello.greeting.GreetingAutoConfiguration

@EnableAutoConfifiguration

  • 加载AutoConfigurationImportSelector类

  • META-INF/spring.factories

    • org.springframework.boot.autoconfigure.EnableAutoConfiguration

spring.factories 文件

注意:
/spring.factories: 定位自动配置
@Configuration注解和/spring.factories文件可以只写一个,建议两个都写

二、实现起步依赖(启动加载)
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

@Slf4j
public class GreetingApplicationRunner implements ApplicationRunner {
    public GreetingApplicationRunner() {

        log.info("Initializing GreetingApplicationRunner.");
    }

    public void run(ApplicationArguments args) throws Exception {
        log.info("Hello everyone! We all like Spring! ");
    }
}

实现ApplicationRunner 接口可以实现起步加载

默认配置核心是对Conditiona相关注解的运用
起步加载核心:ApplicationRunner

我们来看一下spring-boot-autoconfigure 中的META-INF/spring.factories文件写了哪些内容

# Initializers 初始化 
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners 监听器
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

#以上是于spring-cloud-context相关的jar




# Auto Configuration Import Listeners 自动配置监听器
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters 自动配置过滤器
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Auto Configure 自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
#...
#springboot自动配置都在这里配置,把你的配置类权限限定名写在这里

#以上是于spring-boot-autoconfigure相关的jar



# Failure analyzers  故障分析
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer


# Template availability providers 模板
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

@Conditional 用法

使用@Conditional控制@Configuration 是否生效

作用:总而言之,只有@Conditional指定的条件成立,才给容器添加组件

@Conditional派生注解:@Conditional派生了很多注解,下面给个表格列举一下派生注解的用法

@Conditional派生注解作用(都是判断是否符合指定的条件)
@ConditionalOnJava系统的java版本是否符合要求
@ConditionalOnBeanspring容器有指定的Bean类
@ConditionalOnMissingBeanspring容器没有指定的bean类
@ConditionalOnExpression符合指定的SpEL表达式
@ConditionalOnClass有指定的类(好像是你的工程中存在这个类)
@ConditionalOnMissingClass没有指定的类(好像是你的工程中不存在这个类)
@ConditionalOnSingleCandidate容器只有一个指定的bean,或者这个bean是首选bean
@ConditionalOnProperty指定的property属性有指定的值
@ConditionalOnResource路径下存在指定的资源
@ConditionalOnWebApplication系统环境是web环境
@ConditionalOnNotWebApplication系统环境不是web环境
@ConditionalOnjndiJNDI存在指定的项
@ConditionalOnClass

某个class位于类路径上,才会实例化一个Bean。即判断当前classpath下是否存在指定类,若是则将当前的配置装载入spring容器

ConditionalOnProperty

application.properties 属性值符合指定条件时生效

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {
	//获取对应property名称的值,与name不可同时使用
    String[] value() default {};   
  	//property名称的前缀,可有可无
    String prefix() default "";  
  	//property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用 
    String[] name() default {}; 
  	//可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置  
    String havingValue() default "";
  	//缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错  
    boolean matchIfMissing() default false;
  	//是否可以松散匹配,指命名方式支持驼峰横线方式兼容 
    boolean relaxedNames() default true; 
} 
}

其中name用来从application.properties中读取某个属性值。如果该值为空,则返回false(havingValue = "true"时返回true,默认havingValue = “false”);
如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。
如果返回值为false,则该configuration不生效;为true则生效。

代码:https://github.com/liuyanqing1023/geektime-spring-family/tree/master/Chapter%209

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值