spring-boot @SpringBootApplication探究

/**
 * 主程序,说明这是一个SpringBoot应用
 */
@SpringBootApplication
public class HellospringbootApplication {

    public static void main(String[] args) {
        //启动SpringBoot应用
        SpringApplication.run(HellospringbootApplication.class, args);
    }

}

被@SpringBootApplication标注的类是springboot的主程序类

springboot就该运行这个类的main方法来启动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 {};


    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
    String[] excludeName() default {};


    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    /**
     * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
     * scan for annotated components. The package of each class specified will be scanned.
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

}

被@SpringBootConfiguration标注的类是springboot的主配置类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

@Configuration配置类,功能与配置文件一样,可以给spring容器注入组件,它是spring定义的注解。而配置类本身也是容器中的一个组件,因为它有@Component注解。

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

    
    String value() default "";

}

被@Component标注的类,代表一个组件

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {

    
    String value() default "";

}

被@EnableAutoConfiguration的类会开启自动配置功能。

@EnableAutoConfiguration也是一个组合注解
EnableAutoConfigurationImportSelector(开启自动配置类的导包选择器)——导入哪些组件的选择器。它的父类AutoConfigurationImportSelector会通过String[] selectImports(AnnotationMetadata annotationMetadata)方法,以全类名的方式返回,这些组件就会被添加到容器中。它会给容器导入非常多的(场景所需要的组件)自动配置类(*AutoConfiguration),并配置好这些(组件)类。

自动配置类,免去了我们手动编写配置,注入组件等操作

点击查看AutoConfigurationImportSelector做了哪些事

SpringBoot在启动的时候从类路径下的

/META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作。

@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    Class<?>[] exclude() default {};

    /**
     * Exclude specific auto-configuration class names such that they will never be
     * applied.
     * @return the class names to exclude
     * @since 1.3.0
     */
    String[] excludeName() default {};

}

@AutoConfigurationPackage(自动配置包),它将主程序类(被@SpringBootApplication标注的类)的所在包及所有子包的所有组件扫描到spring容器中,@Import导入的组件由Registrar类决定

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

@Import(spring的底层注解)给容器中导入一个组件

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

    /**
     * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
     * or regular component classes to import.
     */
    Class<?>[] value();

}

    @Order(Ordered.HIGHEST_PRECEDENCE)
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
         /*注册bean的定义信息*/
        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata,
                BeanDefinitionRegistry registry) {
            register(registry, new PackageImport(metadata).getPackageName());
        }

        @Override
        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.<Object>singleton(new PackageImport(metadata));
        }

    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容