【Spring Boot】(2)、Hello World探究

1、父项目:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.12.RELEASE</version>
</parent>

其父项目是:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

该父项目是真正管理Spring Boot应用里面的所有依赖的版本:Spring Boot的版本仲裁中心,所以以后导入的依赖默认是不需要版本号。


2、启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter : spring boot场景启动器;帮助导入web模块正常运行所依赖的组件;

​ Spring Boot将所有的功能场景抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter,那么相关的场景的所有依赖都会导入进项目中。要用什么功能就导入什么场景的启动器。


3、主程序类(主入口类)

/**
 * @SpringBootApplication来标注一个主程序类,说明这是一个SpringBoot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {
        //Spring应用启动
        SpringApplication.run(HelloWorldMainApplication.class, args);
    }
}

3.1、@SpringBootApplication

  • Spring Boot应用标注在某个类上,说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。

注解定义如下:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}

3.2、@SpringBootConfiguration:

  • Spring Boot的配置类

  • 标注在某个类上,表示这是一个Spring Boot的配置类

注解定义如下:

扫描二维码关注公众号,回复: 146978 查看本文章
@Configuration
public @interface SpringBootConfiguration {}

3.3、@Configuration:

  • Spring的配置类

  • 标注该注解,对应Spring应用中的配置文件,其底层就是也就是容器中的一个组件 @Component注解定义如下:

@Component
public @interface Configuration {}


3.4、@EnableAutoConfiguration:

  • 开启自动配置功能

  • 以前使用Spring需要配置的信息,Spring Boot帮助自动配置;

  • @EnableAutoConfiguration通知SpringBoot开启自动配置功能,这样自动配置才能生效。注解定义如下:

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

3.5、@AutoConfigurationPackage:

自动配置包注解
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}

3.6、@Import:

  • Spring底层注解

  • 给容器中导入组件,组件由 @Import 的value值指定;

  • @Import(AutoConfigurationPackages.Registrar.class):默认将主配置类(@SpringBootApplication)所在的包及其子包里面的所有组件扫描到Spring容器中。

@Order(Ordered.HIGHEST_PRECEDENCE)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

  	@Override
  	public void registerBeanDefinitions(AnnotationMetadata metadata,
  			BeanDefinitionRegistry registry) {
          //默认将会扫描@SpringBootApplication标注的主配置类所在的包及其子包下所有组件
  		register(registry, new PackageImport(metadata).getPackageName());
  	}

  	@Override
  	public Set<Object> determineImports(AnnotationMetadata metadata) {
  		return Collections.<Object>singleton(new PackageImport(metadata));
  	}
}

@Import(EnableAutoConfigurationImportSelector.class): 给容器中导入组件

EnableAutoConfigurationImportSelector: 导入哪些组件的选择器,将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。

//EnableAutoConfigurationImportSelector的父类:AutoConfigurationImportSelector
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    try {
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
            .loadMetadata(this.beanClassLoader);
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        List<String> configurations = getCandidateConfigurations(annotationMetadata,
                                                                 attributes);
        configurations = removeDuplicates(configurations);
        configurations = sort(configurations, autoConfigurationMetadata);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = filter(configurations, autoConfigurationMetadata);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return configurations.toArray(new String[configurations.size()]);
    }
    catch (IOException ex) {
        throw new IllegalStateException(ex);
    }
}
其中 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 会给容器中注入众多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

有了自动配置类,免去了手动编写配置类注入功能组件等工作。



protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
        getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
	//...
    return configurations;
}
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";


public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        //从类路径的META-INF/spring.factories中加载所有默认的自动配置类
        Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                                 ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        List<String> result = new ArrayList<String>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            //获取EnableAutoConfiguration指定的所有值
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
        }
        return result;
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                                           "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
}

总结:SpringBoot启动的时候从类路径下的 META-INF/spring.factories中获取EnableAutoConfiguration指定的值,并将这些值作为自动配置类导入到容器中,自动配置类就会生效,最后完成自动配置工作。

J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-xxx.jar中。


====================打个广告,欢迎关注====================

QQ:
412425870
微信公众号:Cay课堂

csdn博客:
http://blog.csdn.net/caychen
码云:
https://gitee.com/caychen/
github:
https://github.com/caychen

点击群号或者扫描二维码即可加入QQ群:

328243383(1群)




点击群号或者扫描二维码即可加入QQ群:

180479701(2群)




猜你喜欢

转载自blog.csdn.net/caychen/article/details/79967192