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);
        }
    }
原文地址:https://www.cnblogs.com/fanxl/p/9123017.html