摘要: Spring Boot 核心特性之组件自动装配
@Component
、@Service
、@Configuration
…<context:componet-scan>
或@ComponentScan
@Component
是一种由Spring 容器托管的通用模式组件
Spring Framework 注解 | 场景 | version |
---|---|---|
@Repository | 数据仓储模式注解 | 2.0 |
@Component | 通用组件模式注解 | 2.5 |
@Service | 服务模式注解 | 2.5 |
@Controller | Web 控制器模式注解 | 2.5 |
@Configuration | 配置类模式注解 | 3.0 |
“派生性”(“基注解”<”派生注解”),可以参考以上注解实现自定义注解:
@Component
<@Repository
<CustomRepository
Spring Framework从3.1开始支持@Enable 模块驱动
,模块是指具备相同领域的功能组件集合组合成为一个独立的单元
举例:
@Enable 注解模块 | 模块说明 |
---|---|
@EnableWebMvc | Web MVC模块 |
@EnableAsync | 异步处理模块 |
@EnableAutoConfiguration | 自动配置模块 |
@EnableEurekaClient | Eureka Client模块 |
注解驱动方式 version:3.0 举例: org.springframework.web.servlet.config.annotation.EnableWebMvc
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {}
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}
接口编程方式 version:3.1 举例: org.springframework.boot.autoconfigure.EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector
public class EnableAutoConfigurationImportSelector
extends AutoConfigurationImportSelector {}
public class AutoConfigurationImportSelector
implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
BeanFactoryAware, EnvironmentAware, Ordered {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {}
}
Spring Framework从3.1开始支持在Bean 装配时增加前置条件判断
@Configuration
@Profile("development")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {}
}
@Configuration
@Profile("production")
public class JndiDataConfig {
@Bean
public DataSource dataSource() throws Exception {}
}
@Configuration
public class SomeConfig {
@Bean("dataSource")
@Profile("development")
public DataSource standaloneDataSource() {}
@Bean("dataSource")
@Profile("production")
public DataSource jndiDataSource() throws Exception {}
}
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();
@Conditional 编程方式条件装配 version:4.0 举例:
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {}
激活:@EnableAutoConfiguration
Spring Boot 默认没有激活自动装配,存在@SpringBootApplication注解中
参考:org.springframework.boot.autoconfigure.AutoConfigurationImport
Selector#getCandidateConfigurations
配置:/META-INF/spring.factories
规约文件,META-INFO指的是元信息目录,如spring.handlers、spring.schemas等
参考:org.springframework.core.io.support.SpringFactoriesLoader
实现:XxxAutoConfiguration
ex: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
ImportSelector
部分org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
//加载spring-boot-autoconfigure-1.5.6.RELEASE.jar!\META-INF\spring-autoconfigure-metadata.properties
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
//获取EnableAutoConfiguration里的exclude和excludeName-->LinkedHashMap-->AnnotationAttributes
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取依赖里所有的xx.jar!\META-INF\spring.factories的value
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
//利用Set去重
configurations = removeDuplicates(configurations);
//排序->先按照字母排序->再按照Order排序(ex:MessageSourceAutoConfiguration#@AutoConfigureOrder)->然后根据@AutoConfigureBefore @AutoConfigureAfter(ex:WebSocketAutoConfiguration#@AutoConfigureBefore)排序
configurations = sort(configurations, autoConfigurationMetadata);
//对attributes封装与去重得到exclusions
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
//去掉exclusions里的XxAutoConf...
configurations.removeAll(exclusions);
//加载过滤器,对不满足ex:默认有一个OnClassCondition(org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationImportFilters(),见下图)的会排除掉()
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
ImportSelector
部分org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
org.springframework.context.annotation.ConfigurationClassParser#processDeferredImportSelectors
String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);