绿色环保材料网站模板,北京商场打折,厦门网站建设方案维护,泰州建筑人才网概述 Spring Boot自动装配是其核心特性之一#xff0c;它能够根据项目中添加的依赖自动配置Spring应用程序。通过自动装配#xff0c;开发人员可以减少大量的配置工作#xff0c;快速搭建起一个可用的Spring应用。 关键组件和注解 SpringBootApplication注解 这是Spring Bo… 概述 Spring Boot自动装配是其核心特性之一它能够根据项目中添加的依赖自动配置Spring应用程序。通过自动装配开发人员可以减少大量的配置工作快速搭建起一个可用的Spring应用。 关键组件和注解 SpringBootApplication注解 这是Spring Boot应用的主注解它是一个组合注解实际上包含了Configuration、EnableAutoConfiguration和ComponentScan三个注解。Configuration表明这个类是一个配置类用于定义Spring的Bean。在配置类中可以通过Bean注解方法来创建和配置Bean实例。例如Configuration
public class AppConfig {Beanpublic MyService myService() {return new MyServiceImpl();}
}这里定义了一个名为myService的Bean类型是MyService其实现是MyServiceImpl。 EnableAutoConfiguration这是自动装配的关键注解。它会启用Spring Boot的自动配置机制告诉Spring Boot去根据项目的依赖和配置自动配置应用。它通过Import注解导入了AutoConfigurationImportSelector类来实现自动配置的功能。ComponentScan用于扫描指定包及其子包下的组件如Component、Service、Repository、Controller等注解标记的类将它们注册为Spring的Bean。默认情况下它会扫描主应用类所在的包及其子包。例如如果主应用类在com.example.myapp包下那么ComponentScan会扫描com.example.myapp及其所有子包下的组件。 AutoConfigurationImportSelector类 这个类是自动装配的核心实现类。它实现了ImportSelector接口该接口的selectImports方法用于返回要导入的配置类的全限定名数组。在AutoConfigurationImportSelector中selectImports方法会从META - INF/spring.factories文件中读取自动配置类的列表。它通过SpringFactoriesLoader.loadFactoryNames方法来加载这些配置类例如public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}这里的getAutoConfigurationEntry方法会获取需要自动导入的配置类这些配置类是根据项目中的依赖和条件来确定的。 META - INF/spring.factories文件机制 这是自动装配的重要配置文件。在Spring Boot的各个依赖中都可以包含META - INF/spring.factories文件。这个文件的格式是key value的形式其中一个关键的配置项是org.springframework.boot.autoconfigure.EnableAutoConfiguration。它的值是一个自动配置类的列表例如org.springframework.boot.autoconfigure.EnableAutoConfiguration\org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\// 其他自动配置类当Spring Boot启动时AutoConfigurationImportSelector会读取这些文件找到所有的自动配置类。然后根据条件注解如ConditionalOnClass、ConditionalOnMissingBean等来判断这些自动配置类是否应该被应用。条件注解示例 ConditionalOnClass这个注解用于判断某个类是否在类路径上。例如DataSourceAutoConfiguration中有如下注解Configuration
ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
public class DataSourceAutoConfiguration {// 配置内容
}这表示只有当DataSource类和EmbeddedDatabaseType类都在类路径上时DataSourceAutoConfiguration这个自动配置类才会被应用。这样可以确保只有在项目中添加了相关的数据源依赖时才会进行数据源的自动配置。 ConditionalOnMissingBean用于判断某个类型的Bean是否不存在。例如在某个自动配置类中定义一个方法来配置一个BeanBean
ConditionalOnMissingBean
public MyBean myBean() {return new MyBeanImpl();
}这表示只有当容器中不存在MyBean类型的Bean时才会创建并添加MyBeanImpl这个Bean到容器中。 自动配置的过程 Spring Boot应用启动时首先会加载主应用类由于SpringBootApplication注解的存在Configuration注解使得这个类被视为一个配置类ComponentScan开始扫描组件。同时EnableAutoConfiguration触发自动装配过程。AutoConfigurationImportSelector从各个依赖的META - INF/spring.factories文件中获取自动配置类列表。然后对于每个自动配置类根据条件注解来检查是否满足应用条件。如果满足条件就会将这个自动配置类加载到Spring容器中自动配置类中的Bean方法会被调用创建和配置相应的Bean从而完成自动装配的过程。
具体源码讲解 SpringBootApplication注解源码分析 首先查看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 AutoExcludeFilter.class)
})
public class SpringBootApplication {
}可以看到它是一个组合注解包含了SpringBootConfiguration、EnableAutoConfiguration和ComponentScan。SpringBootConfiguration它实际上就是Configuration注解用于标识这个类是一个配置类。 Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Configuration
public class SpringBootConfiguration {
}EnableAutoConfiguration这是自动装配的关键。它的源码如下 Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Inherited
AutoConfigurationPackage
Import(AutoConfigurationImportSelector.class)
public class EnableAutoConfiguration {
}其中Import(AutoConfigurationImportSelector.class)是核心部分。这个AutoConfigurationImportSelector类用于加载自动配置类。ComponentScan用于扫描组件它有一些默认的扫描规则和可以自定义的过滤规则如上述代码中的excludeFilters用于排除某些类型的组件扫描。 AutoConfigurationImportSelector源码分析 AutoConfigurationImportSelector实现了ImportSelector接口其中关键的方法是selectImports Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}这个方法首先检查自动配置是否启用。然后通过AutoConfigurationMetadataLoader.loadMetadata加载自动配置元数据再通过getAutoConfigurationEntry获取自动配置项。深入getAutoConfigurationEntry方法 protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes getAttributes(annotationMetadata);ListString configurations getCandidateConfigurations(annotationMetadata, attributes);configurations removeDuplicates(configurations);SetString exclusions getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}在这里getCandidateConfigurations方法用于获取候选的自动配置类列表它会从META - INF/spring.factories文件中读取相关配置 protected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {ListString 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;
}SpringFactoriesLoader.loadFactoryNames方法会读取META - INF/spring.factories文件查找org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类列表。 META - INF/spring.factories文件读取源码分析 SpringFactoriesLoader类用于读取spring.factories文件关键方法是loadFactoryNames public static ListString loadFactoryNames(Class? factoryType, Nullable ClassLoader classLoader) {String factoryTypeName factoryType.getName();return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}它调用了loadSpringFactories方法 private static MapString, ListString loadSpringFactories(Nullable ClassLoader classLoader) {MultiValueMapString, String result cache.get(classLoader);if (result! null) {return result;}try {EnumerationURL urls (classLoader! null?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result new LinkedMultiValueMap();while (urls.hasMoreElements()) {URL url urls.nextElement();UrlResource resource new UrlResource(url);Properties properties PropertiesLoaderUtils.loadProperties(resource);for (Map.EntryObject, Object entry : properties.entrySet()) {String factoryTypeName ((String) entry.getKey()).trim();for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryTypeName, factoryImplementationName.trim());}}}cache.put(classLoader, result);return result;} catch (IOException ex) {throw new IllegalArgumentException(Unable to load factories from location [ FACTORIES_RESOURCE_LOCATION ], ex);}
}这个方法首先检查缓存中是否已经有读取的结果。如果没有就通过ClassLoader获取META - INF/spring.factories文件的URL然后将其内容读取到Properties对象中。最后将文件中的配置解析出来以key - value的形式存储在MultiValueMap中其中key是配置项的类型如org.springframework.boot.autoconfigure.EnableAutoConfigurationvalue是对应的配置类列表。 条件注解的源码体现以ConditionalOnClass为例 ConditionalOnClass注解用于判断某个类是否在类路径上。它的实现基于Condition接口。当Spring容器在处理自动配置类时会检查条件注解。ConditionalOnClass对应的Condition实现类是OnClassCondition。在自动配置类加载过程中会调用OnClassCondition的matches方法来判断条件是否满足 Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 省略部分代码ListString onClasses getCandidates(metadata, ConditionalOnClass.class);if (onClasses! null) {ListString missing filter(onClasses, ClassNameFilter.MISSING, context);if (!missing.isEmpty()) {return false;}}ListString onMissingClasses getCandidates(metadata, ConditionalOnMissingClass.class);if (onMissingClasses! null) {ListString present filter(onMissingClasses, ClassNameFilter.PRESENT, context);if (!present.isEmpty()) {return false;}}return true;
}这个方法会获取ConditionalOnClass注解中指定的类列表然后检查这些类是否在类路径上。如果有任何一个指定的类不存在就返回false表示条件不满足自动配置类不会被加载。通过这样的机制Spring Boot可以根据类的存在与否来决定自动配置类的加载与否实现智能的自动装配。