springboot自动配置原理

springboot自动配置原理

1. @SpringBootApplication注解
/**
 * @SpringBootApplication来标注一个主程序类,说明这是一个SpringBoot应用
* */
@SpringBootApplication
public class SpringBoot02ConfigAutoconfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot02ConfigAutoconfigApplication.class, args);
    }

}

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot 就应该运行这个类的main方法来启动SpringBoot应用;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {

@SpringBootConfifiguration:Spring Boot的配置类;

标注在某个类上,表示这是一个Spring Boot的配置类;

@Confifiguration:配置类上来标注这个注解;

配置类 ----- 配置文件;配置类也是容器中的一个组件;@Component

@EnableAutoConfifiguration:开启自动配置功能;

以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfifiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {

@AutoConfigurationPackage:自动配置包

@Import({Registrar.class})
public @interface AutoConfigurationPackage {

Spring的底层注解@Import,给容器中导入一个组件;导入的组件由AutoConfifigurationPackages.Registrar.class;将主配置类(@SpringBootApplication标注的类)的所在包及下面的所有组件扫描到Spring容器;

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {

AutoConfigurationImportSelector:导入哪些类的选择器;

将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;

会给容器中导入非常多的配置类(xxxAutoConfiguration);就是给容器中导入场景需要的所有组件,并配置好组件。

有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;

@EnableAutoConfiguration 注解通过Spring 提供的 @Import 注解导入了AutoConfigurationImportSelector类(@Import 注解可以导入配置类或者Bean到当前类中)。

``AutoConfigurationImportSelector类中getCandidateConfigurations方法会将所有自动配置类的信息以 List 的形式返回。这些配置信息会被 Spring 容器作 bean 来管理。

 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) 
 {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
    }

Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfifiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;

二、自动配置原理
1.自动配置原理:

1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration

  1. 、EnableAutoConfiguration作用:
  • ​ 利用EnableAutoConfigurationImportSelector给容器中导入一些组件;

  • ​ 可以查看selectImports()方法的内容;

  • ​ List confifigurations = getCandidateConfifigurations(annotationMetadata, attributes);获取候选的配置

SpringFactoriesLoader.loadFactoryNames() 

//扫描所有jar包类路径下 META‐INF/spring.factories 

//把扫描到的这些文件的内容包装成properties对象 

//从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfifiguration的值加入到了容器中;

# 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,\ 

org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ 

org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ 

org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ 

org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ 

org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ 

org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ 

org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ 

org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration, 

\

org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ 

org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration 

,\

org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ 

org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration 

,\

org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ 

org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration 

每一个这样的 xxxAutoConfifiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

3)、每一个自动配置类进行自动配置功能;

4)、以HttpEncodingAutoConfifiguration**(Http编码自动配置)**为例解释自动配置原理;

@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件 

@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中 

@ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效 

@ConditionalOnClass(CharacterEncodingFilter.class)// 判断当前项目有没有这个类 CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器; 

@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = 

true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的,即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的; 

public class HttpEncodingAutoConfiguration { 

//他已经和SpringBoot的配置文件映射了 

private final HttpEncodingProperties properties;
    //只有一个有参构造器的情况下,参数的值就会从容器中拿 
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; }
    @Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取 
    @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件
    public CharacterEncodingFilter characterEncodingFilter() 
    { 
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();          filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }

根据当前不同的条件判断,决定这个配置类是否生效?

一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取

的,这些类里面的每一个属性又是和配置文件绑定的;

5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功

能对应的这个属性类

@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定 

public class HttpEncodingProperties { 

`public static final Charset DEFAULT_CHARSET = Charset.forName("UTF‐8"); 

精髓:
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这
些属性的值;

xxxxAutoConfifigurartion:自动配置类;

给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

2、细节

1、@Conditional派生注解(Spring注解版原生的@Conditional作用作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;



`@Conditional扩展注解                         作用(判断是否满足当前指定条件)` 

`@ConditionalOnJava                            系统的java版本是否符合要求` 

`@ConditionalOnBean                           容器中存在指定Bean;` 

`@ConditionalOnMissingBean              容器中不存在指定Bean;` 

`@ConditionalOnExpression                 满足SpEL表达式指定` 

`@ConditionalOnClass                           系统中有指定的类` 

`@ConditionalOnMissingClass                    系统中没有指定的类` 

`@ConditionalOnSingleCandidate                 容器中只有一个指定的Bean,或者这个Bean是首选Bean` 

`@ConditionalOnProperty                        系统中指定的属性是否有指定的值` 

`@ConditionalOnResource                        类路径下是否存在指定资源文件` 

`@ConditionalOnWebApplication                  当前是web环境` 

`@ConditionalOnNotWebApplication               当前不是web环境` 

`@ConditionalOnJndi                            JNDI存在指定项` 

自动配置类必须在一定的条件下才能生效;

我们怎么知道哪些自动配置类生效;

我们可以通过启用 debug=true****属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#开启Spring Boot的debug
debug=true
============================
CONDITIONS EVALUATION REPORT
============================


Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

   AopAutoConfiguration.ClassProxyingConfiguration matched:
      - @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
      - @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
      - found 'session' scope (OnWebApplicationCondition)

   DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
      - @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' (OnClassCondition)
      - Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
      - 
Negative matches:
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

   AopAutoConfiguration.AspectJAutoProxyingConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)

   ArtemisAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

   BatchAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)

注:本文内容参考尚硅谷spring boot笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot自动配置原理简述 SpringBoot自动配置SpringBoot的一大特色,它提供了一种简洁的方式来配置应用程序。在SpringBoot中,我们可以通过添加特定的依赖来自动配置应用程序的各种组件,例如数据源、日志、Web服务等。使用自动配置可以大大简化应用程序的配置过程,减少开发人员的工作量,提高开发效率。 自动配置的实现原理是基于Spring的条件化配置机制。SpringBoot会根据应用程序的依赖和当前环境自动配置各种组件。条件化配置可以通过在类上添加@Conditional注解来实现,该注解可以指定一个条件类,只有满足该条件类的条件时,才会进行配置。例如,以下代码示例中,只有当classpath中存在H2数据库驱动程序时,才会自动配置H2的数据源。 @Configuration @ConditionalOnClass(org.h2.Driver.class) public class H2DataSourceAutoConfiguration { // 配置H2数据源 } 除了依赖条件外,SpringBoot还支持很多其他条件,例如环境条件、属性条件、Bean条件等。通过组合这些条件,可以实现更加灵活的自动配置。例如,以下代码示例中,只有当当前环境为开发环境时,才会自动配置开发环境的日志。 @Configuration @Profile("dev") public class DevLoggerAutoConfiguration { // 配置开发环境的日志 } 总之,SpringBoot自动配置机制是基于Spring的条件化配置机制实现的,它可以根据应用程序的依赖和当前环境自动配置各种组件,大大简化了应用程序的配置过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值