• spring boot 自动配置


    1.Spring boot 自动配置

    spring boot 通过@springbootapplication来启动项目,使用@springbootapplication标记过的类证明是这个类的主程序,程序通过运行这个类的main方法来启动这个程序

    @SpringBootApplication
    public class SpringBootTestApp {
        public static void main(String[] args){
            //启动注册中心
            SpringApplication.run(SpringBootTestApp.class,args);
        }

    @SpringBootApplication 该类中主要包含了@SpringBootConfiguration@EnableAutoConfiguration等五个注解

    /**
    该注解标记了@Springbootapplication这个注解可以标记在什么位置上,@Target可以应用于TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER 修饰类型用于类的、TYPE_USE,TYPE修饰类、接口、枚举,FIELD 属性,METHOD 方法,PARAMETER 方法上的参数,CONSTRUCTOR用于构造方法,LOCAL_VARIABLE 局部变量,ANNOTATION_TYPE 注解,PACKAGE 修饰包 TYPE_PARAMETER 修饰类型用于泛型,TYPE_USE 修饰类型只要是类型名称都可以使用该注解*/
    @Target({ElementType.TYPE})
    /**
    Retention该注解标明了此注解的生命周期,RetentionPolicy.SOURC:只标识在源码阶段,RetentionPolicy.CLASS:注解保留在class文件中,在加载到虚拟机是被丢弃
    RetentionPolicy.RUNTIME:保留在程序运行期间,此时可以通过反射获取定义在某个元素上的注解
    */
    @Retention(RetentionPolicy.RUNTIME)
    /**
    @Documented 注解表明这个注解应该被 javadoc工具记录,默认javadoooc不记录注解
    */
    @Documented
    /**说注解和普通类的区别是如果一个子类想获取到父类上的注解信息,
    那么必须在父类上使用的注解上面 加上@Inherit关键字 */
    @Inherited
    /**
    @SpringBootConfiguration 使用该注解标识的类为springboot项目的配置类
    */
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}

    1.@SpringBootConfiguration

    @SpringBootConfiguration 使用该注解标识的类为springboot项目的配置类

    @SpringBootConfiguration 使用了@configuration注解标识这个类为配置类

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

    @configuration使用了@component标识了,证明了这个类会被spring boot 管理(

    @Service用于标注业务层组件

    @Controller用于标注控制层组件(如struts中的action)

    @Repository用于标注数据访问组件,即DAO组件,

    @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注)

    2.@EnableAutoConfiguration

    @EnableAutoConfiguration 字面理解为开启自动注解,该注解又依赖于@**AutoConfigurationPackage**
    
    @Import(**AutoConfigurationPackage**.class)。
    
    
    @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 {};
    }

    1.AutoConfigurationPackage

    @AutoConfigurationPackage依赖于Import,import 用于将AutoConfigurationPackages声明注册到Spring 容器中

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

    AutoConfigurationPackages.package,通过这个方法获取@springbootapplication标注类的所在包下的所有组件扫描

    
        /**
         * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
         * configuration.
         */
        @Order(Ordered.HIGHEST_PRECEDENCE)
        static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    
            @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));
            }
        }

    2.EnableAutoConfigurationImportSelector

    @Import(EnableAutoConfigurationImportSelector.class)将EnableAutoConfigurationImportSelector注册到spring 中,EnableAutoConfigurationImportSelector继承了AutoConfigurationImportSelector

    public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
        @Override
        protected boolean isEnabled(AnnotationMetadata metadata) {
            if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {
                return getEnvironment().getProperty(                    EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,
                        true);
            }
            return true;
        }
    }

    AutoConfigurationImportSelector读取了spring.factories这个配置文件并将里边的配置自动配置类加载到spring容器中并对spring boot 进行

    
    @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            }
            try {
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                        .loadMetadata(this.beanClassLoader);
                AnnotationAttributes attributes = getAttributes(annotationMetadata);
                List<String> configurations = getCandidateConfigurations(annotationMetadata,
                        attributes);
                configurations = removeDuplicates(configurations);
                configurations = sort(configurations, autoConfigurationMetadata);
                Set<String> exclusions = getExclusions(annotationMetadata, attributes);
                checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = filter(configurations, autoConfigurationMetadata);
                fireAutoConfigurationImportEvents(configurations, exclusions);
                return configurations.toArray(new String[configurations.size()]);
            }
            catch (IOException ex) {
                throw new IllegalStateException(ex);
            }
        }
  • 相关阅读:
    Beyond Compare 4 过期操作
    python2 批量转 python3
    【JavaScript】为什么javascript是单线程
    Java之花样玩枚举
    OpenSSL
    OpenSSL和OpenSSH以及私有CA的实现
    Python-线程同步
    Zookeeper基础
    pycharm中使用git以及多分支结构
    BZOJ 4771 主席树+倍增+set
  • 原文地址:https://www.cnblogs.com/fanxl/p/9123017.html
Copyright © 2020-2023  润新知