springboot自动配置原理(高低版本比较)spring.factories文件的作用

news2025/1/22 4:21:37
@SpringBootApplication
public class SpringSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityApplication.class, args);
    }

}

注解@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
)
Class<?>[] exclude() default {};

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

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

@AliasFor(
    annotation = ComponentScan.class,
    attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};

@AliasFor(
    annotation = ComponentScan.class,
    attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

@AliasFor(
    annotation = Configuration.class
)
boolean proxyBeanMethods() default true;

}



核心3个注解:
@SpringBootConfiguration     改注解和@Configuration类似,表面这个类是配置类
@EnableAutoConfiguration    springboot实现自动化配置的核心注解
@ComponentScan    默认扫描启动类当前包以及子包

要了解springboot自动配置原理当然我们需要看@EnableAutoConfiguration

在这2.4版本以前
@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 {};

}

3.4.1版本
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = “spring.boot.enableautoconfiguration”;

Class<?>[] exclude() default {};

String[] excludeName() default {};

}

开启自动配置注解我们需要看这个注解做了什么事?
看上面的代码我们可以发现一个关键的@import注解,
低版本:开启导入自动配置选择器:
源码:
@Deprecated
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
    public EnableAutoConfigurationImportSelector() {
    }

    protected boolean isEnabled(AnnotationMetadata metadata) {
        return this.getClass().equals(EnableAutoConfigurationImportSelector.class) ? (Boolean)this.getEnvironment().getProperty("spring.boot.enableautoconfiguration", Boolean.class, true) : true;
    }
}
``

3.4.1版本
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    static final int ORDER = 2147483646;
    private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
    private static final String[] NO_IMPORTS = new String[0];
    private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
    private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
    private final Class<?> autoConfigurationAnnotation;
    private ConfigurableListableBeanFactory beanFactory;
    private Environment environment;
    private ClassLoader beanClassLoader;
    private ResourceLoader resourceLoader;
    private volatile ConfigurationClassFilter configurationClassFilter;
    private volatile AutoConfigurationReplacements autoConfigurationReplacements;

    public AutoConfigurationImportSelector() {
        this((Class)null);
    }

    AutoConfigurationImportSelector(Class<?> autoConfigurationAnnotation) {
        this.autoConfigurationAnnotation = autoConfigurationAnnotation != null ? autoConfigurationAnnotation : AutoConfiguration.class;
    }

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

    public Predicate<String> getExclusionFilter() {
        return this::shouldExclude;
    }

    private boolean shouldExclude(String configurationClassName) {
        return this.getConfigurationClassFilter().filter(Collections.singletonList(configurationClassName)).isEmpty();
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    }

    public Class<? extends DeferredImportSelector.Group> getImportGroup() {
        return AutoConfigurationGroup.class;
    }

    protected boolean isEnabled(AnnotationMetadata metadata) {
        return this.getClass() == AutoConfigurationImportSelector.class ? (Boolean)this.getEnvironment().getProperty("spring.boot.enableautoconfiguration", Boolean.class, true) : true;
    }

    protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
        String name = this.getAnnotationClass().getName();
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
        Assert.notNull(attributes, () -> {
            String var10000 = metadata.getClassName();
            return "No auto-configuration attributes found. Is " + var10000 + " annotated with " + ClassUtils.getShortName(name) + "?";
        });
        return attributes;
    }

    protected Class<?> getAnnotationClass() {
        return EnableAutoConfiguration.class;
    }

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation, this.getBeanClassLoader());
        List<String> configurations = importCandidates.getCandidates();
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/" + this.autoConfigurationAnnotation.getName() + ".imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

    private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
        List<String> invalidExcludes = new ArrayList(exclusions.size());
        Iterator var4 = exclusions.iterator();

        while(var4.hasNext()) {
            String exclusion = (String)var4.next();
            if (ClassUtils.isPresent(exclusion, this.getClass().getClassLoader()) && !configurations.contains(exclusion)) {
                invalidExcludes.add(exclusion);
            }
        }

        if (!invalidExcludes.isEmpty()) {
            this.handleInvalidExcludes(invalidExcludes);
        }

    }

    protected void handleInvalidExcludes(List<String> invalidExcludes) {
        StringBuilder message = new StringBuilder();
        Iterator var3 = invalidExcludes.iterator();

        while(var3.hasNext()) {
            String exclude = (String)var3.next();
            message.append("\t- ").append(exclude).append(String.format("%n"));
        }

        throw new IllegalStateException(String.format("The following classes could not be excluded because they are not auto-configuration classes:%n%s", message));
    }

    protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        Set<String> excluded = new LinkedHashSet();
        excluded.addAll(this.asList(attributes, "exclude"));
        excluded.addAll(this.asList(attributes, "excludeName"));
        excluded.addAll(this.getExcludeAutoConfigurationsProperty());
        return this.getAutoConfigurationReplacements().replaceAll(excluded);
    }

    protected List<String> getExcludeAutoConfigurationsProperty() {
        Environment environment = this.getEnvironment();
        if (environment == null) {
            return Collections.emptyList();
        } else if (environment instanceof ConfigurableEnvironment) {
            Binder binder = Binder.get(environment);
            return (List)binder.bind("spring.autoconfigure.exclude", String[].class).map(Arrays::asList).orElse(Collections.emptyList());
        } else {
            String[] excludes = (String[])environment.getProperty("spring.autoconfigure.exclude", String[].class);
            return excludes != null ? Arrays.asList(excludes) : Collections.emptyList();
        }
    }

    protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
    }

    private ConfigurationClassFilter getConfigurationClassFilter() {
        ConfigurationClassFilter configurationClassFilter = this.configurationClassFilter;
        if (configurationClassFilter == null) {
            List<AutoConfigurationImportFilter> filters = this.getAutoConfigurationImportFilters();
            Iterator var3 = filters.iterator();

            while(var3.hasNext()) {
                AutoConfigurationImportFilter filter = (AutoConfigurationImportFilter)var3.next();
                this.invokeAwareMethods(filter);
            }

            configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);
            this.configurationClassFilter = configurationClassFilter;
        }

        return configurationClassFilter;
    }

    private AutoConfigurationReplacements getAutoConfigurationReplacements() {
        AutoConfigurationReplacements autoConfigurationReplacements = this.autoConfigurationReplacements;
        if (autoConfigurationReplacements == null) {
            autoConfigurationReplacements = AutoConfigurationReplacements.load(this.autoConfigurationAnnotation, this.beanClassLoader);
            this.autoConfigurationReplacements = autoConfigurationReplacements;
        }

        return autoConfigurationReplacements;
    }

    protected final <T> List<T> removeDuplicates(List<T> list) {
        return new ArrayList(new LinkedHashSet(list));
    }

    protected final List<String> asList(AnnotationAttributes attributes, String name) {
        String[] value = attributes.getStringArray(name);
        return Arrays.asList(value);
    }

    private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
        List<AutoConfigurationImportListener> listeners = this.getAutoConfigurationImportListeners();
        if (!listeners.isEmpty()) {
            AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
            Iterator var5 = listeners.iterator();

            while(var5.hasNext()) {
                AutoConfigurationImportListener listener = (AutoConfigurationImportListener)var5.next();
                this.invokeAwareMethods(listener);
                listener.onAutoConfigurationImportEvent(event);
            }
        }

    }

    protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader);
    }

    private void invokeAwareMethods(Object instance) {
        if (instance instanceof Aware) {
            if (instance instanceof BeanClassLoaderAware) {
                BeanClassLoaderAware beanClassLoaderAwareInstance = (BeanClassLoaderAware)instance;
                beanClassLoaderAwareInstance.setBeanClassLoader(this.beanClassLoader);
            }

            if (instance instanceof BeanFactoryAware) {
                BeanFactoryAware beanFactoryAwareInstance = (BeanFactoryAware)instance;
                beanFactoryAwareInstance.setBeanFactory(this.beanFactory);
            }

            if (instance instanceof EnvironmentAware) {
                EnvironmentAware environmentAwareInstance = (EnvironmentAware)instance;
                environmentAwareInstance.setEnvironment(this.environment);
            }

            if (instance instanceof ResourceLoaderAware) {
                ResourceLoaderAware resourceLoaderAwareInstance = (ResourceLoaderAware)instance;
                resourceLoaderAwareInstance.setResourceLoader(this.resourceLoader);
            }
        }

    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory);
        this.beanFactory = (ConfigurableListableBeanFactory)beanFactory;
    }

    protected final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        this.beanClassLoader = classLoader;
    }

    protected ClassLoader getBeanClassLoader() {
        return this.beanClassLoader;
    }

    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    protected final Environment getEnvironment() {
        return this.environment;
    }

    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    protected final ResourceLoader getResourceLoader() {
        return this.resourceLoader;
    }

    public int getOrder() {
        return 2147483646;
    }

    protected static class AutoConfigurationEntry {
        private final List<String> configurations;
        private final Set<String> exclusions;

        private AutoConfigurationEntry() {
            this.configurations = Collections.emptyList();
            this.exclusions = Collections.emptySet();
        }

        AutoConfigurationEntry(Collection<String> configurations, Collection<String> exclusions) {
            this.configurations = new ArrayList(configurations);
            this.exclusions = new HashSet(exclusions);
        }

        public List<String> getConfigurations() {
            return this.configurations;
        }

        public Set<String> getExclusions() {
            return this.exclusions;
        }
    }

    private static class ConfigurationClassFilter {
        private final AutoConfigurationMetadata autoConfigurationMetadata;
        private final List<AutoConfigurationImportFilter> filters;

        ConfigurationClassFilter(ClassLoader classLoader, List<AutoConfigurationImportFilter> filters) {
            this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(classLoader);
            this.filters = filters;
        }

        List<String> filter(List<String> configurations) {
            long startTime = System.nanoTime();
            String[] candidates = StringUtils.toStringArray(configurations);
            boolean skipped = false;
            Iterator var6 = this.filters.iterator();

            int i;
            while(var6.hasNext()) {
                AutoConfigurationImportFilter filter = (AutoConfigurationImportFilter)var6.next();
                boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);

                for(i = 0; i < match.length; ++i) {
                    if (!match[i]) {
                        candidates[i] = null;
                        skipped = true;
                    }
                }
            }

            if (!skipped) {
                return configurations;
            } else {
                List<String> result = new ArrayList(candidates.length);
                String[] var12 = candidates;
                int var14 = candidates.length;

                for(i = 0; i < var14; ++i) {
                    String candidate = var12[i];
                    if (candidate != null) {
                        result.add(candidate);
                    }
                }

                if (AutoConfigurationImportSelector.logger.isTraceEnabled()) {
                    int numberFiltered = configurations.size() - result.size();
                    AutoConfigurationImportSelector.logger.trace("Filtered " + numberFiltered + " auto configuration class in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
                }

                return result;
            }
        }
    }

    private static final class AutoConfigurationGroup implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
        private final Map<String, AnnotationMetadata> entries = new LinkedHashMap();
        private final List<AutoConfigurationEntry> autoConfigurationEntries = new ArrayList();
        private ClassLoader beanClassLoader;
        private BeanFactory beanFactory;
        private ResourceLoader resourceLoader;
        private AutoConfigurationMetadata autoConfigurationMetadata;
        private AutoConfigurationReplacements autoConfigurationReplacements;

        private AutoConfigurationGroup() {
        }

        public void setBeanClassLoader(ClassLoader classLoader) {
            this.beanClassLoader = classLoader;
        }

        public void setBeanFactory(BeanFactory beanFactory) {
            this.beanFactory = beanFactory;
        }

        public void setResourceLoader(ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }

        public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
            Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> {
                return String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName());
            });
            AutoConfigurationImportSelector autoConfigurationImportSelector = (AutoConfigurationImportSelector)deferredImportSelector;
            AutoConfigurationReplacements autoConfigurationReplacements = autoConfigurationImportSelector.getAutoConfigurationReplacements();
            Assert.state(this.autoConfigurationReplacements == null || this.autoConfigurationReplacements.equals(autoConfigurationReplacements), "Auto-configuration replacements must be the same for each call to process");
            this.autoConfigurationReplacements = autoConfigurationReplacements;
            AutoConfigurationEntry autoConfigurationEntry = autoConfigurationImportSelector.getAutoConfigurationEntry(annotationMetadata);
            this.autoConfigurationEntries.add(autoConfigurationEntry);
            Iterator var6 = autoConfigurationEntry.getConfigurations().iterator();

            while(var6.hasNext()) {
                String importClassName = (String)var6.next();
                this.entries.putIfAbsent(importClassName, annotationMetadata);
            }

        }

        public Iterable<DeferredImportSelector.Group.Entry> selectImports() {
            if (this.autoConfigurationEntries.isEmpty()) {
                return Collections.emptyList();
            } else {
                Set<String> allExclusions = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
                Set<String> processedConfigurations = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
                processedConfigurations.removeAll(allExclusions);
                return this.sortAutoConfigurations(processedConfigurations, this.getAutoConfigurationMetadata()).stream().map((importClassName) -> {
                    return new DeferredImportSelector.Group.Entry((AnnotationMetadata)this.entries.get(importClassName), importClassName);
                }).toList();
            }
        }

        private AutoConfigurationMetadata getAutoConfigurationMetadata() {
            if (this.autoConfigurationMetadata == null) {
                this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            }

            return this.autoConfigurationMetadata;
        }

        private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
            MetadataReaderFactory var10002 = this.getMetadataReaderFactory();
            AutoConfigurationReplacements var10004 = this.autoConfigurationReplacements;
            Objects.requireNonNull(var10004);
            return (new AutoConfigurationSorter(var10002, autoConfigurationMetadata, var10004::replace)).getInPriorityOrder(configurations);
        }

        private MetadataReaderFactory getMetadataReaderFactory() {
            try {
                return (MetadataReaderFactory)this.beanFactory.getBean("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", MetadataReaderFactory.class);
            } catch (NoSuchBeanDefinitionException var2) {
                return new CachingMetadataReaderFactory(this.resourceLoader);
            }
        }
    }
}

在这里插入图片描述

对于spring.factories文件
3.4.1版本
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

1.5.2版本
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnClassCondition

3.4.1版本可以看到,实现方式发生了变化,引入了配置类过滤器ConfigurationClassFilter来完成bean自动配置的加载
在这里插入图片描述
调用getAutoConfigurationEntry来获取要自动配置的类放入AutoConfigurationEntry对象,这个对象包含2个集合,一个是要自动配置的集合,一个是排除自动配置的集合
在这里插入图片描述在这里插入图片描述
spring会跟进这两个集合完成自动配置

低版本的只需要读取spring.factories文件,获取自动配置类进行自动加载bean

spring.factories文件自动配置信息

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

总结:
1.通过@SpringBootConfiguration 引入了@EnableAutoConfiguration(负责启动自动配置功能)
2.@EnableAutoConfiguration引入了@Import
3.Spring容器启动时:加载loc容器时会解析@Import 注解
4.@lmport导入了一个deferredlmportSelector,它会使SpringBoot的自动配置类的顺序在最后,这样方便我们扩展和覆盖?
5.然后读取所有的/META-INF/spring.factories文件(SPI)
6.过滤出所有AutoConfigurtionClass类型的类
7.最后通过@Condition排除无效的自动配置类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2280150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

总结4..

#include <stdio.h> // 定义全局变量n&#xff0c;用于表示二维数组的大小 // 定义二维数组b&#xff0c;用于标记找到单词的位置&#xff0c;初始化为0 int n, b[200][200] {0}; // 定义二维数组d&#xff0c;存储8个方向的偏移量&#xff0c;用于在二维数组中搜索…

从零开始:Spring Boot核心概念与架构解析

引言 在当今的Java开发领域&#xff0c;Spring Boot已经成为构建企业级应用的首选框架之一。它以其简洁、高效、易于上手的特点&#xff0c;极大地简化了Spring应用的开发过程。本文将从Spring Boot的核心概念入手&#xff0c;深入解析其架构设计和运行原理&#xff0c;帮助读…

深入 Flutter 和 Compose 的 PlatformView 实现对比,它们是如何接入平台控件

在上一篇《深入 Flutter 和 Compose 在 UI 渲染刷新时 Diff 实现对比》发布之后&#xff0c;收到了大佬的“催稿”&#xff0c;想了解下 Flutter 和 Compose 在 PlatformView 实现上的对比&#xff0c;恰好过去写过不少 Flutter 上对于 PlatformView 的实现&#xff0c;这次恰好…

无人机飞手考证难度增加,实操、地面站教学技术详解

随着无人机技术的快速发展和广泛应用&#xff0c;无人机飞手考证的难度确实在不断增加。这主要体现在对飞手的实操技能和地面站操作技术的要求上。以下是对无人机飞手考证中实操和地面站教学技术的详细解析&#xff1a; 一、实操教学技术详解 1. 无人机基础知识学习&#xff1…

linux下springboot项目nohup日志或tomcat日志切割处理方案

目录 1. 配置流程 2. 配置说明 其他配置选项&#xff1a; 3. 测试执行 4. 手动执行 https://juejin.cn/post/7081890486453010469 通常情况下&#xff0c;我们的springboot项目部署到linux服务器中&#xff0c;通过nohup java -jar xxx.jar &指令来进行后台运行我们…

知识图谱可视化:揭示隐藏的模式与关系

目录 前言1. 什么是知识图谱可视化1.1 知识图谱概述1.2 知识图谱可视化的定义 2. 知识图谱可视化的意义2.1 降低理解门槛2.2 帮助发现模式与洞察2.3 提升交互性与用户体验 3. 知识图谱可视化的技术实现3.1 数据处理与准备3.2 可视化技术3.3 用户交互设计 4. 知识图谱可视化的应…

深度学习基础--LSTM学习笔记(李沐《动手学习深度学习》)

前言 LSTM是RNN模型的升级版&#xff0c;神经网络模型较为复杂&#xff0c;这里是学习笔记的记录&#xff1b;LSTM比较复杂&#xff0c;可以先看&#xff1a; 深度学习基础–一文搞懂RNN 深度学习基础–GRU学习笔记(李沐《动手学习深度学习》) RNN&#xff1a;RNN讲解参考&am…

电气防火保护器为高校学生宿舍提供安全保障

摘 要&#xff1a;3月2日&#xff0c;清华大学紫荆学生公寓发生火情&#xff0c;无人员伤亡。推断起火原因系中厅内通电电器发生故障引燃周边可燃物所致。2月27日&#xff0c;贵州某高校女生宿舍发生火灾&#xff0c;现场明火得到有效控制&#xff0c;无人员受伤。2月19日&…

每打开一个chrome页面都会【自动打开F12开发者模式】,原因是 使用HBuilderX会影响谷歌浏览器的浏览模式

打开 HBuilderX&#xff0c;点击 运行 -> 运行到浏览器 -> 设置web服务器 -> 添加chrome浏览器安装路径 chrome谷歌浏览器插件 B站视频下载助手插件&#xff1a; 参考地址&#xff1a;Chrome插件 - B站下载助手&#xff08;轻松下载bilibili哔哩哔哩视频&#xff09…

C#使用WMI获取控制面板中安装的所有程序列表

C#使用WMI获取控制面板中安装的所有程序列表 WMI 全称Windows Management Instrumentation,Windows Management Instrumentation是Windows中用于提供共同的界面和对象模式以便访问有关操作系统、设备、应用程序和服务的管理信息。如果此服务被终止&#xff0c;多数基于 Windo…

企业级流程架构设计思路-基于价值链的流程架构

获取更多企业流程资料 纸上得来终觉浅&#xff0c;绝知此事要躬行 一.企业流程分级规则定义 1.流程分类分级的总体原则 2.完整的流程体系需要体现出流程的分类分级 03.通用的流程分级方法 04.流程分级的标准 二.企业流程架构设计原则 1.流程架构设计原则 流程框架是流程体…

PyTorch使用教程(8)-一文了解torchvision

一、什么是torchvision torchvision提供了丰富的功能&#xff0c;主要包括数据集、模型、转换工具和实用方法四大模块。数据集模块内置了多种广泛使用的图像和视频数据集&#xff0c;如ImageNet、CIFAR-10、MNIST等&#xff0c;方便开发者进行训练和评估。模型模块封装了大量经…

如何将自己本地项目开源到github上?

环境&#xff1a; LLMB项目 问题描述&#xff1a; 如何将自己本地项目开源到github上&#xff1f; 解决方案&#xff1a; 步骤 1: 准备本地项目 确保项目整洁 确认所有的文件都在合适的位置&#xff0c;并且项目的 README.md 文件已经完善。检查是否有敏感信息&#xff0…

ConvBERT:通过基于跨度的动态卷积改进BERT

摘要 像BERT及其变体这样的预训练语言模型最近在各种自然语言理解任务中取得了令人印象深刻的性能。然而&#xff0c;BERT严重依赖于全局自注意力机制&#xff0c;因此存在较大的内存占用和计算成本。尽管所有的注意力头都从全局角度查询整个输入序列以生成注意力图&#xff0…

2025web建议

随便收集的信息 新手入门路线推荐 第一步&#xff1a;Web安全相关概念 建议学习时间&#xff1a;2周 学习内容如下&#xff1a; 1、熟悉基本概念(SQL注入、上传、XSS、CSRF、一句话木马等)。 2、通过关键字(SQL注入、上传、XSS、CSRF、一句话木马等)进行Google。 3、阅读《Web…

用JAVA实现人工智能:采用框架Spring AI Java

Spring AI 集成人工智能&#xff0c;为Java项目添加AI功能指南 本文主旨是用实际的可操作的代码&#xff0c;介绍Java怎么通过spring ai 接入大模型。 例子使用spring ai alibaba QWen千问api完成&#xff0c;你可以跑通以后换自己的实现。QWen目前有100万免费Token额度&…

【JDBC】数据库连接的艺术:深入解析数据库连接池、Apache-DBUtils与BasicDAO

文章目录 前言&#x1f30d; 一.连接池❄️1. 传统获取Conntion问题分析❄️2. 数据库连接池❄️3.连接池之C3P0技术&#x1f341;3.1关键特性&#x1f341;3.2配置选项&#x1f341;3.3使用示例 ❄️4. 连接池之Druid技术&#x1f341; 4.1主要特性&#x1f341; 4.2 配置选项…

canvas 图片组合并进行下载

运行图片&#xff1a; 思路&#xff1a;先画一个背景图片&#xff0c;再画一个二维码定位到你想要的位置&#xff0c;最后直接下载即可&#xff0c;可以扩散一下思维&#xff0c;画简单的海报的时候&#xff0c;也可以的 源代码 <!DOCTYPE html> <html lang"en&q…

记一次升级请求创建报错问题的调查过程(Windchill)

问题现象描述&#xff1a; ​ 新建申请请求单&#xff0c;在选择某些物料时会报此错误&#xff0c;选另外的物料时又可以正常创建&#xff0c;不报此错误。 问题原因分析&#xff1a; ​ 1.分析后台日志 —没有任何进展&#xff0c;此报错应该是前端的报错 ​ 2.从前端下手…

自旋锁与CAS

上文我们认识了许许多多的锁&#xff0c;此篇我们的CAS就是从上文的锁策略开展的新概念&#xff0c;我们来一探究竟吧 1. 什么是CAS&#xff1f; CAS: 全称Compare and swap&#xff0c;字⾯意思:“比较并交换”&#xff0c;⼀个CAS涉及到以下操作&#xff1a; 我们假设内存中…