减脂餐,大拇指,茂名天气-牛码头,活禽交易市场,最新农产品数据发布

admin 2019-07-18 阅读:309

本章意图

探究springboot背面的注解,逐步解开其奥秘面纱。

体系版别

  1. jdk1.8
  2. springboot 2.1.6.RELEASE
  3. 开发工具(IntelliJ IDEA 2018.1.5 x64)
  4. apache maven(3.6.0,本章选用maven方式办理jar包,详细装备环境变量以及运用请自行查找材料)
  5. 开端。。。
  6. 咱们首要剖析进口类Application的发动注解@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 {
...
}

明显 @SpringBootApplication是一个复合注解,包含以下三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

下面咱们一起来看下

@SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

@SpringBootConfiguration承继自@Configuration,二者功用也共同,标示当时类是装备类,

并会将当时类内声明的一个或多个以@Bean注解符号的办法的实例归入到spring容器中,而且实例名便是办法名。

@ComponentScan

@ComponentScan主动扫描并加载契合条件的组件(比方@Component和@Repository等)或许bean界说,最终将这些bean界说加载到IoC容器中。是曾经的(曾经运用在XML中运用的标签,用来扫描包装备的平行支撑)。

咱们能够经过basePackages等特点来细粒度的定制@ComponentScan主动扫描的规模,假如不指定,则默许Spring结构完成会从声明@ComponentScan地点类的package进行扫描。

这两个注解,并不是 springboot特有的,spring年代现已有了,对咱们来说并不生疏,今日咱们的主角:@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
//是否敞开主动安装 默许为true,可在yml文件中设置
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
//依据class来扫除
Class
//依据class name来扫除
String[] excludeName() default {};
}

@EnableAutoConfiguration

主动装备是springboot的最大亮点,完美的展现了CoC约好因为装备。此注解,正是敞开主动装备的中心。

从源码中,能够看到注解@Import,@Import(AutoConfigurationImportSelector.class)

@AutoConfigurationImportSelector

 @Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
...
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
...
//获取类途径下spring.factories下key为EnableAutoConfiguration全限定名对应值
List configurations = getCandidateConfigurations(annotationMetadata, attributes);
...
}
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//EnableAutoConfiguration.class
List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
...
}

@SpringFactoriesLoader

 public static  List loadFactories(Class factoryClass, @Nullable ClassLoader classLoader) {
...
List factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
...
}
public static List loadFactoryNames(Class
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
...
//读取META-INF/spring.factories文件的装备,并回来一个字符串数组
Enumeration urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
...
}

至此,springboot主动安装的奥秘面纱现已解开。

总结:@EnableAutoConfiguration效果

  • 从classpath中查找一切META-INF/spring.factories装备文件,将其间key为org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的装备项加载到spring容器。
  • spring.boot.enableautoconfiguration为true(默许为true)的时分,才启用主动装备
  • 自界说扫除某些不需要的主动装备
  • 依据class来扫除(exclude)
  • 依据class name来扫除(excludeName)

代码要害点

  1. ImportSelector(AutoConfigurationImportSelector) 该接口的办法的回来值都会被归入到spring容器办理中
  2. SpringFactoriesLoader 从classpath中查找一切META-INF/spring.factories装备文件,并读取装备。

疑问

  • @import、ImportSelector、ImportBeanDefinitionRegistrar各有什么用?
  • spring的bpp是什么?
  • Enable*的原理是什么?

下一章,咱们带着这些疑问,持续探究源码。