[SB框架]SpringBoot一些技巧

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_36964056/article/details/85324471

1.随机端口

为Spring Cloud的应用实用随机端口非常简单,主要有两种方法:
设置server.port=0,当应用启动的时候会自动的分配一个随机端口,但是该方式在注册到Eureka的时候会一个问题:所有实例都使用了同样的实例名(如:Lenovo-test:hello-service:0),这导致只出现了一个实例。所以,我们还需要修改实例ID的定义,让每个实例的ID不同,比如使用随机数来配置实例ID:

server.port=0
eureka.instance.instance-id=${spring.application.name}:${random.int}

除了上面的方法,实际上我们还可以直接使用random函数来配置server.port。这样就可以指定端口的取值范围,比如:

server.port=${random.int[10000,19999]}

由于默认的实例ID会由server.port拼接,而此时server.port设置的随机值会重新取一次随机数,所以使用这种方法的时候不需要重新定义实例ID的规则就能产生不同的实例ID了。

2.SpringBoot流程分析

  1. 运行流程
    1. 判断是不是Web环境
    2. 加载所有classpath下面的META-INF/spring.factorties ApplicationContextInitializer
    3. 加载所有classpath下面的META-INF/spring.factorties ApplicationListener
    4. 推断main方法所在的类
    5. 开始执行run方法
    6. 设置java.awt.headless系统变量
    7. 加载所有classpath下面的META-INF/spring.factorties SpringApplicationRunnerListener
    8. 执行所有SpringApplicationRunnerListener的started方法
    9. 实例化ApplicationArguments对象
    10. 创建environment
    11. 配置environment,主要是把run方法的参数配置到environment中
    12. 执行所有SpringApplicationRunnerListener的environmentPrepared方法
    13. 如果不是web环境,但是是web的environment,则把这个web的environment转换长标准的environment
    14. 打印banner
    15. 初始化applicationContext,如果是web环境,则实例化AnnotationConfigEmbeddedWebApplicationContext对象,否则实例化AnnotationConfigApplicationContext对象
    16. 如果beanNameGenerator不为空,就把beanNameGenerator对象注入到applicationContext里面去
    17. 回调所有的ApplicationContextInitializer方法
    18. 执行所有SpringApplicationRunnerListener的contextPrepared方法
    19. 依次往spring容器中注入:ApplicationArguments,Banner
    20. 加载所有的源到applicationContext里面去
    21. 执行所有SpringApplicationRunnerListener的contextLoaded方法
    22. 执行applicationContext的refresh方法,并且调用applicationContext的registerShutdownHook方法
    23. 回调,获取容器中所有的ApplicationRunner,CommandLineRunner接口,然后排序,依次调用
    24. 执行所有SpringApplicationRunnerListener的finished方法

3.使用CommandLineRunner

CommandLineRunner是Spring容器启动成功后的最后一步回调
使用步骤

  1. 写一个类实现CommandLineRunner接口
  2. 通过@Component将它交给容器管理
    详细代码
@Order(1)
@Component
public class ServerSuccessReport implements CommandLineRunner {;

    private Logger logger= LoggerFactory.getLogger(getClass());

    @Override
    public void run(String... arg0) throws Exception {
        logger.info("==================应用程序启动完成=====================");
        logger.info("参数:{}",arg0.getClass());
    }
}

@Order
来制定CommandLineRunner 执行顺序

package com.springboot.study.course7;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author huang
 * @PACKAGE_NAME com.springboot.study.course7
 * @PROJECT_NAME springboot
 * @date 2018/12/25
 */

@Order(2)
@Component
public class ServerSuccessReport2 implements CommandLineRunner {;

    private Logger logger= LoggerFactory.getLogger(getClass());

    @Override
    public void run(String... arg0) throws Exception {
        logger.info("==================应用程序启动时间:{}", LocalDateTime.now().toString());
    }
}

通过@Order(param)来控制多个CommandLineRunner实现类的执行顺序,param参数数字最大,最早执行。

猜你喜欢

转载自blog.csdn.net/weixin_36964056/article/details/85324471