一、Spring Boot入门

作者: 木石前盟Caychen | 来源:发表于2019-04-18 14:33 被阅读2次

    1、Spring Boot简介

    简化Spring应用开发的一个框架;
    整个Spring技术栈的一个大整合;
    J2EE开发的一站式解决方案;

    2、微服务

    微服务:架构风格;
    一个应用应该是一组小型服务,可以用过HTTP的方式进行沟通;
    每一个功能元素最终都是一个可独立替换和独立升级的软件单元;

    3、开发环境:略

    4、Spring Boot HelloWorld

    项目功能:浏览器发送hello请求,服务器接受请求并处理和响应。

    4.1、创建一个maven工程(jar)

    略。

    4.2、导入依赖spring boot相关的依赖

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

    4.3、编写主程序

    //HelloWorldMainApplication.class
    /**
     * @SpringBootApplication来标注一个主程序类,说明这是一个SpringBoot应用
     */
    @SpringBootApplication
    public class HelloWorldMainApplication {
    
        public static void main(String[] args) {
            //Spring应用启动
            SpringApplication.run(HelloWorldMainApplication.class, args);
        }
    }
    

    4.4、编写相关的Controller、Service

    @RestController
    public class HelloController {
    
        @RequestMapping("/hello")
        public String hello(){
            return "Hello world";
        }
    }
    

    4.5、运行主程序测试

    4.6、简化部署

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    

    使用maven打包命令将其打包成jar包后,直接使用命令:

        java -jar xxx.jar
    

    使该应用启动起来。

    5、Hello World探究

    5.1、POM文件

    5.1.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.12.RELEASE</version>
        <relativePath>../../spring-boot-dependencies</relativePath>
    </parent>
    

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

    5.1.2、启动器

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

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

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

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

    /**
     * @SpringBootApplication来标注一个主程序类,说明这是一个SpringBoot应用
     */
    @SpringBootApplication
    public class HelloWorldMainApplication {
    
        public static void main(String[] args) {
            //Spring应用启动
            SpringApplication.run(HelloWorldMainApplication.class, args);
        }
    }
    

    5.2.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 {}
    

    5.2.2、@SpringBootConfiguration:

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

    注解定义如下:

    @Configuration
    public @interface SpringBootConfiguration {}
    

    5.2.3、@Configuration:

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

    5.2.4、@EnableAutoConfiguration:

    • 开启自动配置功能
    • 以前使用Spring需要配置的信息,Spring Boot帮助自动配置;
    • @EnableAutoConfiguration通知SpringBoot开启自动配置功能,这样自动配置才能生效。
      注解定义如下:
    @AutoConfigurationPackage
    @Import(EnableAutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {}
    

    5.2.5、@AutoConfigurationPackage:

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

    5.2.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),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

    SpringBoot自动配置类.png

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

    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中。

    6、使用Spring Initializer快速创建Spring Boot项目

    IDE(IDEA, STS)都支持使用Spring的项目创建向导快速创建一个SpringBoot项目。

    • src/main/java
    • src/main/resources
      • static: 所有的静态资源(css/js/images/...)
      • templates: 所有的模版页面
      • application.properties: Spring Boot应用的配置文件,可以修改SpringBoot的默认配置。
    • src/test/java

    相关文章

      网友评论

        本文标题:一、Spring Boot入门

        本文链接:https://www.haomeiwen.com/subject/dmxtgqtx.html