Spring Boot 自定义Logo 以及控制台打印启动地址

Spring Boot 自定义Logo 以及控制台打印启动地址

1. 自定义Logo

原理: Spring Boot 的一个内置特性,用于在应用程序启动时显示一个“横幅”(banner)。
自动检测banner.txt

  • 当 Spring Boot 应用程序启动时,它会自动在类路径(classpath)的根目录下查找名为 banner.txt 的文件。在 Maven/Gradle 项目中,src/main/resources 目录下的内容会被复制到类路径的根目录。
  • 如果找到了 banner.txt 文件,Spring Boot 会读取其内容并在应用程序启动日志的最开始(或非常靠前的位置)将其打印到控制台。

简单来说,只要 Spring Boot 应用启动时能在类路径的根目录找到一个名为 banner.txt 的文件,它就会默认打印出来。
目的:这个 banner 通常用来显示应用程序的名称、版本号、ASCII 艺术的 Logo,或者任何开发者想在启动时展示的欢迎信息。

1.1 默认的Spring Logo

Spring Boot 在启动时会显示一个 ASCII 艺术的 LOGO(默认为 Spring 的标志)。

我们也可以自定义,就是替换 banner.txt 文件(放置自定义的 ASCII 图案)

1.2 如何自定义Logo

1.2.1 创建自定义banner.txt 文件

在项目 <src/main/resources 目录下创建或替换 banner.txt文件

1.2.2 配置

spring.banner.location:指定Logo文件的路径,默认为classpath:banner.txt。所以如果路径和文件名跟默认一样,可不配置。
spring.banner.charset:字符编码,默认为 UTF-8。可不配置
spring.main.banner-mode:显示方式,默认为 console(控制台输出)。
可选值:
console:在控制台输出(默认)。
log:以日志形式输出(日志级别为 INFO)。
off:禁用商标显示。

1.2.3 如何编辑制作Logo

在线生成工具:https://tool.cccyun.cc/ascii_art
颜色支持:通过 ANSI 转义码添加颜色
一些额外信息:

  • 优先级:如果使用您的 starter 的主应用程序也在其自己的 src/main/resources 目录下放了一个 <banner.txt,那么主应用程序的 banner.txt 通常会覆盖(或优先于)您 starter JAR 中提供的 banner.txt。Spring Boot 只会打印一个 banner.txt 的内容。

2. 控制台打印启动地址

项目结构

2.1 启动类中写

@SpringBootApplication
public class Application {

    private static Logger log = LoggerFactory.getLogger(Application.class);

    public static void main( String[] args ) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
        Environment env         = applicationContext.getEnvironment();
        boolean shouldPrintStartupInfo = env.getProperty("banner.app-startup-enabled", Boolean.class, true);
        if (shouldPrintStartupInfo) {
            logAppStartUp(env);
        }
    }

    /**
     * 打印启动地址
     */
    private static void logAppStartUp(Environment env) {
        String appName = Optional.ofNullable(env.getProperty("spring.application.name"))
                .orElseGet(() -> Optional.ofNullable(env.getProperty("application.name")).orElse(""));

        String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store"))
                .map(key -> "https")
                .orElse("http");

        String port = Optional.ofNullable(env.getProperty("server.port")).orElse("8080");

        String contextPath = Optional.ofNullable(env.getProperty("server.servlet.context-path"))
                .filter(StringUtils::hasText)
                .orElse("/");

        String hostIp = "localhost";
        try {
            hostIp = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            log.warn("Failed to get host address, using 'localhost' as default.", e);
        }

        String docFileName = "doc.html";
        String fullDocPath;
        if ("/".equals(contextPath)) {
            fullDocPath = "/" + docFileName;
        } else if (contextPath.endsWith("/")) {
            fullDocPath = contextPath + docFileName;
        } else {
            fullDocPath = contextPath + "/" + docFileName;
        }

        String[] activeProfiles = env.getActiveProfiles();
        String[] profilesToLog = activeProfiles.length == 0 ? env.getDefaultProfiles() : activeProfiles;
        log.info(
                """
    
                ----------------------------------------------------------
                    Application {} is running! Access URLs:
                    url:   {}://{}:{}{}
                    docs:  {}://{}:{}{}
                    Profile(s): {}
                ----------------------------------------------------------""",
                appName,                               // name
                protocol, hostIp, port, contextPath,   // uRL parts
                protocol, hostIp, port, fullDocPath,   // docs URL parts
                Arrays.toString(profilesToLog)         // profiles
                );
    }
}

2.2 配置类写

public class BannerApplicationRunner implements ApplicationRunner {

    Logger log = LoggerFactory.getLogger(this.getClass());

    private final Environment env;

    public BannerApplicationRunner(Environment env) {
        this.env = env;
    }

    @Override
    public void run(ApplicationArguments args) {

        String appName = Optional.ofNullable(env.getProperty("spring.application.name"))
            .orElseGet(() -> Optional.ofNullable(env.getProperty("application.name")).orElse(""));

        String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store"))
            .map(key -> "https")
            .orElse("http");

        String port = Optional.ofNullable(env.getProperty("server.port")).orElse("8080");

        String contextPath = Optional.ofNullable(env.getProperty("server.servlet.context-path"))
            .filter(StringUtils::hasText)
            .orElse("/");

        String hostIp = "localhost";
        try {
            hostIp = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            log.warn("Failed to get host address, using 'localhost' as default.", e);
        }

        String docFileName = "doc.html";
        String fullDocPath;
        if ("/".equals(contextPath)) {
            fullDocPath = "/" + docFileName;
        } else if (contextPath.endsWith("/")) {
            fullDocPath = contextPath + docFileName;
        } else {
            fullDocPath = contextPath + "/" + docFileName;
        }

        String[] activeProfiles = env.getActiveProfiles();
        String[] profilesToLog = activeProfiles.length == 0 ? env.getDefaultProfiles() : activeProfiles;
        log.info(
            """

            ----------------------------------------------------------
                Application {} is running! Access URLs:
                url:   {}://{}:{}{}
                docs:  {}://{}:{}{}
                Profile(s): {}
            ----------------------------------------------------------""",
            appName,                               // name
            protocol, hostIp, port, contextPath,   // uRL parts
            protocol, hostIp, port, fullDocPath,   // docs URL parts
            Arrays.toString(profilesToLog)         // profiles
        );
    }
}
@Configuration
@ConditionalOnProperty(prefix = "banner-inner", name = "enabled", havingValue = "true", matchIfMissing = false)
public class BannerAutoConfiguration {

    private final Environment env;

    public BannerAutoConfiguration(Environment env) {
        this.env = env;
    }

    @Bean
    @Order()
    public BannerApplicationRunner bannerApplicationRunner() {
        return new BannerApplicationRunner(env);
    }
}

2.3 starter依赖写

项目结构如下,写法还是用配置类的方式。然后用maven install一下。

然后在springboot-banner工程maven中引入一下

springboot-banner的配置文件可以控制banner开关
在这里插入图片描述
我的仓库地址:https://gitee.com/xiaoxingOvO/technical-learn.git

### Spring Boot 自定义启动 Logo 输出 ASCII Art 图形实现方式 #### 1. 使用 `banner.txt` 文件 Spring Boot 提供了一个默认机制来加载自定义启动画面,即通过创建一个名为 `banner.txt` 的文件并将其放置在类路径下的资源目录中(通常是 `src/main/resources/`)。该文件可以包含任何纯文本内容,包括 ASCII 艺术图。当应用程序启动时,Spring Boot 将自动读取此文件的内容并打印控制台[^1]。 #### 2. 创建 ASCII 艺术图 为了生成美观的 ASCII 艺术图,可以利用在线工具完成设计工作。以下是几个常用的 ASCII 字符画生成网站: - **http://patorjk.com/software/taag/**:提供多种字体样式选择,适合快速生成简单的 ASCII 文本。 - **https://www.bootschool.net/ascii-art**:专注于为 Spring Boot 应用程序提供预设的艺术字模板。 - **https://tools.kalvinbg.cn/image/asciiPic**:支持上传图片转换成 ASCII 表示形式[^3]。 例如,假设选择了以下 ASCII 艺术文字作为启动标志: ```text _______ __ _ _ |__ __| / _| | | | | | |_ _ _ __ ___ | |_ __ _ | | __ _| |__ | | | | | '_ ` _ \| _| / _` | | |/ _` | '_ \ | | |_| | | | | | | | | (_| | | | (_| | |_) | |_|\__,_|_| |_| |_|_| \__,_| |_|\__,_|_.__/ ``` 将上述内容保存至 `src/main/resources/banner.txt` 中即可生效。 #### 3. 动态 Banner 设置 如果希望更灵活地管理启动画面,则可以通过编程的方式指定 Banner 的显示逻辑。具体方法如下所示: ```java import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CustomBannerApp { public static void main(String[] args) { SpringApplication application = new SpringApplication(CustomBannerApp.class); // 定义自定义 Banner 显示行为 application.setBanner(new Banner() { @Override public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) { out.println("Custom Dynamic Banner Loaded!"); } }); application.run(args); } } ``` 以上代码片段展示了如何通过重写 `Banner` 接口来自定义启动时的行为[^4]。 #### 4. 基于环境变量调整 Banner 对于复杂的项目结构或者需要根据不同运行条件改变 Banner 展示的情况,推荐采用基于 Profile 或者其他外部化配置手段来进行区分处理。比如,在 `application.properties` 文件里加入类似这样的键值对: ```properties spring.banner.location=classpath:/custom-banner-${profile}.txt ``` 这样就可以依据当前激活 profile 加载不同的 banner 文件了[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值