一、关键注解
AutoConfigurationImportSelector类中selectImports方法:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
==>找到依赖中的META-INF/spring.factories配置文件,自动开启默认配置
补充:@Import注解四种使用
1、直接导入Bean
// 1、直接导入Bean
@Import(User.class)
public class HelloApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(HelloApp.class, args);
2、导入配置类(此时配置类中的@Configuration注解可以不写)
配置类
//@Configuration
public class UserConfig {
@Bean
public User user() {
return new User();
}
@Bean
public Role role() {
return new Role();
}
}
// 2、导入配置类(此时配置类中的@Configuration注解可以不写)
@Import(UserConfig.class)
public class HelloApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(HelloApp.class, args);
//是否注册了User到容器
User user = context.getBean(User.class);
System.out.println(user);
Map<String, User> map = context.getBeansOfType(User.class);
System.out.println(map);
3、导入ImportSelector的实现类(@EnableAutoConfiguration注解内部使用这种方式)
实现类:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.swjtu.domain.User","com.swjtu.domain.Role"};
}
}
// 3、导入ImportSelector的实现类
@Import(MyImportSelector.class)
public class HelloApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(HelloApp.class, args);
4、导入ImportBeanDefinitionRegistrar实现类
实现类:
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
registry.registerBeanDefinition("user",beanDefinition);
}
}
// 4、ImportBeanDefinitionRegistrar
@Import(MyImportBeanDefinitionRegistrar.class)
public class HelloApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(HelloApp.class, args);
二、细节
1. @AutoConfigurationPackage(自动配置包,指定默认的包规则)
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
1.利用Registrar给容器中导入一系列组件
2.将指定的一个包下的所有组件导入进来(启动类所在包下)
2.@Import({AutoConfigurationImportSelector.class})
AutoConfigurationImportSelector类中:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, 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.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
1.利用getAutoConfigurationEntry(annotationMetadata),给容器中批量导入一些组件
2.调用 List configurations = this.getCandidateConfigurations(annotationMetadata, attributes); 获取到所有需要导入到容器中的配置类
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
3.利用这个工厂类加载所有组件,从META-INF/spring.factories位置来加载一个文件
3.按需加载
1.虽然我们所有的自动配置启动时默认全部加载,xxxxAutoConfiguration
2.但按照条件装配规则(@conditionalxxx),最终按需配置
4.整合某个技术
该配置可以这样做:找到该依赖的自动配置类,如:
找到对应场景的注解 @EnableConfigurationProperties({DiscoveryClientHealthIndicatorProperties.class})
@ConfigurationProperties("spring.cloud.discovery.client.health-indicator")
public class DiscoveryClientHealthIndicatorProperties {
private boolean enabled = true;
private boolean includeDescription = false;
public DiscoveryClientHealthIndicatorProperties() {
}
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isIncludeDescription() {
return this.includeDescription;
}
public void setIncludeDescription(boolean includeDescription) {
this.includeDescription = includeDescription;
}
public String toString() {
StringBuffer sb = new StringBuffer("DiscoveryClientHealthIndicatorProperties{");
sb.append("enabled=").append(this.enabled);
sb.append(", includeDescription=").append(this.includeDescription);
sb.append('}');
return sb.toString();
}
}
最后按需在application.properties中修改。
简述