zoukankan      html  css  js  c++  java
  • Spring Cloud微服务实战 打造企业级优惠券系统 3-15 【阶段总结】SpringBoot 的常用特性

    0    课程地址

    https://coding.imooc.com/lesson/380.html#mid=28567

    1    浓缩精华
    2    个人关注
    3    课程内容

    SpringBoot 的常用特性

    SpringBoot 应用启动入口

    • 在SpringBoot的入口类中,我们通常是通过调用SpringApplication的run方法(一个静态方法),另外再加上@SpringBootApplication注解来启动SpringBoot项目
    • 通过调用SpringApplication的方法,调整应用的行为
    • SpringApplicationBuilder提供了Fluent API,可以实现链式调用。我们可以用它来实现刚刚定义的功能,可以发现代码层面在编写上较为方便

    示例代码

    @SpringBootApplication
    public class SpringBootStudyApplication {
    
        public static void main(String[] args) {
    
            // 1. 通过静态 run 方法
            SpringApplication.run(SpringBootStudyApplication.class, args);
    
            // 2. 通过 api 调整应用行为
            SpringApplication application =
                    new SpringApplication(SpringBootStudyApplication.class);
            application.setBannerMode(Banner.Mode.OFF);
            application.setWebApplicationType(WebApplicationType.NONE);
            application.run(args);
    
            // 3. SpringApplicationBuilder Fluent Api, 链式调用
            new SpringApplicationBuilder(SpringBootStudyApplication.class)
                    .bannerMode(Banner.Mode.OFF)
    //                .web(WebApplicationType.NONE)
                    .run(args);
        }
    }
    

    SpringBoot 自动配置原理

    简单的说,自动配置就是会根据在类路径中的jar、类自动配置Bean。Spring Boot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目里面引入这些starter,相关场景的所有依赖都会导入进来。

    • 自动配置就是基于三个重要的注解实现的(实际就是 @SpringBootApplication 注解)
    // @SpringBootConfiguration:我们点进去以后可以发现底层是Configuration注解,其实就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)
    // @EnableAutoConfiguration:这个注解用来开启自动配置,是自动配置实现的核心注解
    // @ComponentScan:这个注解,学过Spring的同学应该对它不会陌生,就是扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan
    public @interface SpringBootApplication {
    }
    
    • @EnableAutoConfiguration源码
    // @AutoConfigurationPackage:自动配置包
    // @Import:给IOC容器导入组件
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    }
    
    • @AutoConfigurationPackage 源码
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage
    
    public void registerBeanDefinitions(AnnotationMetadata metadata,
                    BeanDefinitionRegistry registry) {
      register(registry, new PackageImport(metadata).getPackageName())
            }
    // 很容易可以看到,它的作用就是将主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中
    
    • @Import(AutoConfigurationImportSelector.class) 源码
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            }
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                    .loadMetadata(this.beanClassLoader);
            AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
                    autoConfigurationMetadata, annotationMetadata);
    
    // 可以得到了很多配置信息
    protected AutoConfigurationEntry getAutoConfigurationEntry(...) {
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    
    // 配置信息从这里来
    protected List<String> getCandidateConfigurations(...) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(...);
    
    // 配置加载的位置
    public static List<String> loadFactoryNames(...) {
        String factoryClassName = factoryClass.getName();
        return loadSpringFactories(classLoader)...;
    }
    
    private static Map<String, List<String>> loadSpringFactories(...) {
        Enumeration<URL> urls = (classLoader != null ?
            classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            for (Map.Entry<?, ?> entry : properties.entrySet()) {
                result.add(factoryClassName, factoryName.trim());
    
    // 这个方法也就是自动配置的核心实现了,主要是三点内容:
    // FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
    // Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象
    // 从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。
    

    SpringBoot 配置文件

    • 同一个目录下的 application 和 bootstrap

      • bootstrap 优先级高于 application,优先被加载
      • bootstrap 用于应用程序上下文的引导阶段,由父 ApplicationContext 加载
      • bootstrap 是系统级别的配置(不变的参数),application 是应用级别的配置
    • 不同位置的配置文件加载顺序(优先级)

      • file:./config/ - 优先级最高(项目根路径下的 config)
      • file:./ - 优先级第二(项目根路径下)
      • classpath:/config/ - 优先级第三(项目 resources/config 下)
      • classpath:/ - 优先级第四(项目 resources 目录下)
      • 高优先级覆盖低优先级相同配置、多个配置文件互补

    SpringBoot Actuator监控

    微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的处理和传递,出现了异常如何快速定位是哪个环节出现了问题?
    在这种框架下,微服务的监控显得尤为重要。SpringBoot给我们提供了一个用于监控的组件:Actuator,它也是一个starter,方便在日常的开发、运行中对我们的微服务进行监控治理。

    • Actuator监控分类
      • 应用配置类:可以查看应用在运行期的静态信息:例如自动配置信息、加载的 springbean 信息、yml 文件配置信息、环境信息、请求映射信息
      • 度量指标类:主要是运行期的动态信息,例如堆栈、请求连、一些健康指标、metrics 信息等
      • 操作控制类:主要是指 shutdown,用户可以发送一个请求将应用的监控功能关闭

    配置注入的方式

    • 直接使用 @Value
    • 使用 @ConfigurationProperties + prefix 的方式

    Jackson 的使用技巧

    通常在项目中处理JSON一般用的都是阿里巴巴的fastjson, 后来发现使用Spring Boot内置的Jackson来完成JSON的序列化和反序列化操作也是非常方便的。

    • @JsonProperty,作用在属性上,用来为JSON Key指定一个别名
    • @Jsonlgnore,作用在属性上,用来忽略此属性
    • @JsonIgnoreProperties,忽略一组属性,作用于类上
    • @JsonFormat,用于日期格式化
    • Jackson通过使用ObjectMapper的writeValueAsString方法将Java对象序列化为JSON格式字符串
    • 反序列化使用 ObjectMapper 的 readValue

    定时任务

    • @EnableScheduling:允许当前的应用开启定时任务
    • @Scheduled:指定定时任务的运行规则

    异步任务

    通常代码都是顺序执行(一行一行的执行),这也就是同步调用。但是异步编程却没有这样的限制,代码执行并不是阻塞的。可以直接调用不用等待返回,而是在某一个想要获取结果的时间点再去获取结果。

    • 引入spring-boot-starter-web依赖
    • 在SpringBoot入口类上加上 @EnableAsync 注解,开启异步支持
    • 只需要在方法上加上 @Async 注解,则当前方法就是异步方法

    默认情况下的异步线程池配置使得线程不能被重用,每次调用异步方法都会新建一个线程,我们可以自己定义异步线程池来优化。

    单元测试

    编写单元测试可以帮助开发人员编写高质量的代码,提升代码质量,减少Bug,便于重构。SpringBoot提供了一些实用程序和注解,用来帮助我们测试应用程序,在SpringBoot中开启单元测试只需引入spring-boot-starter-test即可,其包含了一些主流的测试库。

    一个标准的SpringBoot测试用例应该包含两个注解:

    • @SpringBootTest:意思是带有 SpringBoot 支持的引导程序,其中提供了可以指定 Web 环境的参数
    • @RunWith(SpringRunner.class):告诉JUnit运行使用Spring的测试支持。SpringRunner是SpringJUnit4ClassRunner的新名字,这个名字只是让名字看起来简单些
    4    代码演练
    诸葛
  • 相关阅读:
    HDU 1031 Design TShirt
    普利姆(Prime)算法
    hdu 2601 An easy problem
    克鲁斯卡尔(Kruskal)算法
    双调欧几里德旅行商问题hdu 2224 The shortest path POJ 2677Tour
    求一个数个各位相加的结果时
    C语言中各种类型的范围
    获取浏览器的scrollTop有几点小疑问
    学习,学习javascript
    各种翻页的效果! FILTER: revealTrans使用说明
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/14296108.html
Copyright © 2011-2022 走看看