简单理解springboot自动装配的原理

一.概要

首先我们都知道所有的springboot的程序的入口都是有一个@SpringBootApplication来作为程序的入口的,接下来,我们来观察这个注解,其实他是一个复合的注解,点进去,源码如下:

@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 {
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "exclude"
    )
    Class[] exclude() default {};
    ...........
    ...........
    ...........
}

他复合的核心注解主要有以下下面几个:@SpringBootConfiguration、@EnableAutoConfiguration、
@ComponentScan,我们来一个个的去分析这些注解吧。

1.@SpringBootConfiguration:通过观察源码,我们会发现,他是来源于@Configuration注解,他们两者之间的功能也是一样的,就是讲一个类标志为一个配置类,在这个配置类下面,可以有一个或者多个@Bean

2.@ComponentScan:很明显他是表明他扫描的包的

3.@EnableAutoConfiguration:他是自动配置的核心的注解,接下来,我们需要核心的去分析这个注解。

分析@EnableAutoConfiguration

首先,他的源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class[] exclude() default {};

    String[] excludeName() default {};
}

@Import注解

@Import注解可以将一个普通的java类标志为一个Bean
@Import({EnableAutoConfigurationImportSelector.class})导入了类EnableAutoConfigurationImportSelector,在EnableAutoConfigurationImportSelector中,使用loadFactoryNames方法加载自动配置类路径,源码如下:

 protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List 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;
    }

一个实现了自动配置的例子:

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

   @Configuration
   @ConditionalOnMissingBean(ConnectionFactory.class)
   protected static class RabbitConnectionFactoryCreator {

      @Bean
      public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
            throws Exception {
         RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
         //......
         return connectionFactory;
      }

   }
//......
}

你可能感兴趣的:(spring)