zoukankan      html  css  js  c++  java
  • SpringBootApplication注解 专题

    到这里,看到所有的配置是借助SpringFactoriesLoader加载了META-INF/spring.factories文件里面所有符合条件的配置项的全路径名。
    找到spring-boot-autoconfigure包,看到META-INF下的spring.factories文件(果然是你,果然),这里就是自动化配置所有类项的列表

    /**
     * General purpose factory loading mechanism for internal use within the framework.
     *
     * <p>{@code SpringFactoriesLoader} {@linkplain #loadFactories loads} and instantiates
     * factories of a given type from {@value #FACTORIES_RESOURCE_LOCATION} files which
     * may be present in multiple JAR files in the classpath. The {@code spring.factories}
     * file must be in {@link Properties} format, where the key is the fully qualified
     * name of the interface or abstract class, and the value is a comma-separated list of
     * implementation class names. For example:
     *
     * <pre class="code">example.MyService=example.MyServiceImpl1,example.MyServiceImpl2</pre>
     *
     * where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1}
     * and {@code MyServiceImpl2} are two implementations.
     *
     * @author Arjen Poutsma
     * @author Juergen Hoeller
     * @author Sam Brannen
     * @since 3.2
     */
    public abstract class SpringFactoriesLoader {
    
        private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
    
        /**
         * The location to look for factories.
         * <p>Can be present in multiple JAR files.
         */
        public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

    org.springframework.boot.autoconfigure.SpringBootApplication
    之@EnableAutoConfiguration

    package org.springframework.boot.autoconfigure;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.context.TypeExcludeFilter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.core.annotation.AliasFor;
    
    /**
     * Indicates a {@link Configuration configuration} class that declares one or more
     * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
     * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
     * annotation that is equivalent to declaring {@code @Configuration},
     * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
     *
     * @author Phillip Webb
     * @author Stephane Nicoll
     * @since 1.2.0
     */
    @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 {
    
        /**
         * Exclude specific auto-configuration classes such that they will never be applied.
         * @return the classes to exclude
         */
        @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "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
         */
        @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
        String[] excludeName() default {};
    
        /**
         * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
         * for a type-safe alternative to String-based package names.
         * @return base packages to scan
         * @since 1.3.0
         */
        @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.
         * <p>
         * Consider creating a special no-op marker class or interface in each package that
         * serves no purpose other than being referenced by this attribute.
         * @return base packages to scan
         * @since 1.3.0
         */
        @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
        Class<?>[] scanBasePackageClasses() default {};
    
    }

    org.springframework.boot.autoconfigure.EnableAutoConfiguration

    package org.springframework.boot.autoconfigure;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
    import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.core.io.support.SpringFactoriesLoader;
    
    /**
     * Enable auto-configuration of the Spring Application Context, attempting to guess and
     * configure beans that you are likely to need. Auto-configuration classes are usually
     * applied based on your classpath and what beans you have defined. For example, If you
     * have {@code tomcat-embedded.jar} on your classpath you are likely to want a
     * {@link TomcatEmbeddedServletContainerFactory} (unless you have defined your own
     * {@link EmbeddedServletContainerFactory} bean).
     * <p>
     * Auto-configuration tries to be as intelligent as possible and will back-away as you
     * define more of your own configuration. You can always manually {@link #exclude()} any
     * configuration that you never want to apply (use {@link #excludeName()} if you don't
     * have access to them). You can also exclude them via the
     * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied
     * after user-defined beans have been registered.
     * <p>
     * The package of the class that is annotated with {@code @EnableAutoConfiguration} has
     * specific significance and is often used as a 'default'. For example, it will be used
     * when scanning for {@code @Entity} classes. It is generally recommended that you place
     * {@code @EnableAutoConfiguration} in a root package so that all sub-packages and classes
     * can be searched.
     * <p>
     * Auto-configuration classes are regular Spring {@link Configuration} beans. They are
     * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class).
     * Generally auto-configuration beans are {@link Conditional @Conditional} beans (most
     * often using {@link ConditionalOnClass @ConditionalOnClass} and
     * {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations).
     *
     * @author Phillip Webb
     * @author Stephane Nicoll
     * @see ConditionalOnBean
     * @see ConditionalOnMissingBean
     * @see ConditionalOnClass
     * @see AutoConfigureAfter
     */
    @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 {};
    
    }

    org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector

    package org.springframework.boot.autoconfigure;
    
    import org.springframework.context.annotation.DeferredImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    
    /**
     * {@link DeferredImportSelector} to handle {@link EnableAutoConfiguration
     * auto-configuration}. This class can also be subclassed if a custom variant of
     * {@link EnableAutoConfiguration @EnableAutoConfiguration}. is needed.
     *
     * @deprecated as of 1.5 in favor of {@link AutoConfigurationImportSelector}
     * @author Phillip Webb
     * @author Andy Wilkinson
     * @author Stephane Nicoll
     * @author Madhura Bhave
     * @since 1.3.0
     * @see EnableAutoConfiguration
     */
    @Deprecated
    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;
        }
    
    }

    org.springframework.boot.autoconfigure.AutoConfigurationImportSelector
    org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

        @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);
            }
        }

    org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations

        /**
         * Return the auto-configuration class names that should be considered. By default
         * this method will load candidates using {@link SpringFactoriesLoader} with
         * {@link #getSpringFactoriesLoaderFactoryClass()}.
         * @param metadata the source metadata
         * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
         * attributes}
         * @return a list of candidate configurations
         */
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
                AnnotationAttributes attributes) {
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
                    getSpringFactoriesLoaderFactoryClass(), 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;
        }

    org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames

        /**
         * Load the fully qualified class names of factory implementations of the
         * given type from {@value #FACTORIES_RESOURCE_LOCATION}, using the given
         * class loader.
         * @param factoryClass the interface or abstract class representing the factory
         * @param classLoader the ClassLoader to use for loading resources; can be
         * {@code null} to use the default
         * @see #loadFactories
         * @throws IllegalArgumentException if an error occurs while loading factory names
         */
        public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
            String factoryClassName = factoryClass.getName();
            try {
                Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                        ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
                List<String> result = new ArrayList<String>();
                while (urls.hasMoreElements()) {
                    URL url = urls.nextElement();
                    Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                    String factoryClassNames = properties.getProperty(factoryClassName);
                    result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
                }
                return result;
            }
            catch (IOException ex) {
                throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                        "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
            }
        }

    org.springframework.core.io.support.SpringFactoriesLoader#FACTORIES_RESOURCE_LOCATION

    /**
     * General purpose factory loading mechanism for internal use within the framework.
     *
     * <p>{@code SpringFactoriesLoader} {@linkplain #loadFactories loads} and instantiates
     * factories of a given type from {@value #FACTORIES_RESOURCE_LOCATION} files which
     * may be present in multiple JAR files in the classpath. The {@code spring.factories}
     * file must be in {@link Properties} format, where the key is the fully qualified
     * name of the interface or abstract class, and the value is a comma-separated list of
     * implementation class names. For example:
     *
     * <pre class="code">example.MyService=example.MyServiceImpl1,example.MyServiceImpl2</pre>
     *
     * where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1}
     * and {@code MyServiceImpl2} are two implementations.
     *
     * @author Arjen Poutsma
     * @author Juergen Hoeller
     * @author Sam Brannen
     * @since 3.2
     */
    public abstract class SpringFactoriesLoader {
    
        private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
    
        /**
         * The location to look for factories.
         * <p>Can be present in multiple JAR files.
         */
        public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";







  • 相关阅读:
    用 Flask 来写个轻博客 (19) — 以 Bcrypt 密文存储账户信息与实现用户登陆表单
    用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象
    用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象
    用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目
    用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目
    Nginx详解八:Nginx基础篇之Nginx请求限制的配置语法与原理
    Nginx详解七:Nginx基础篇之Nginx官方模块
    Nginx详解六:Nginx基础篇之Nginx日志
    Nginx详解五:Nginx基础篇之HTTP请求
    Nginx详解四:Nginx基础篇之目录和配置语法
  • 原文地址:https://www.cnblogs.com/softidea/p/7148755.html
Copyright © 2011-2022 走看看