从零开始 Spring Boot 5:SpringApplication

从零开始 Spring Boot 5:SpringApplication

spring boot

图源:简书 (jianshu.com)

我们的Spring Boot应用是通过SpringApplication.run启动的,启动后可以看到控制台输出欢迎信息以及一些日志信息,如果失败,也会显示相应的错误信息。

SpringApplication的主要工作是加载相关的配置,创建Web应用的上下文,以及启动应用等。

下面介绍和SpringApplication相关的Spring Boot特性。

本篇文章的演示代码基于learn_spring_boot (github.com)修改而来,你可以从相应的链接获取。

Lazy Initialization

Lazy Initialization也可以叫做“延迟初始化”或“懒加载”,这是一个常用的Web技术,比如大量图片的展示网页,就会在用户下滑需要展示相应图片时再真正加载图片资源,这可以节省一开始网页加载的时间和带宽。

Sprint Boot中,这指的是可以将相关创建和注入bean的行为延后到真正需要这些bean的时候,这样做可以加快应用的启动速度。但缺点是如果bean的生成会产生bug,那么就无法在一开始应用启动时暴露,而是延后到使用bean时,这样就违背了“尽可能早地暴露bug”这条编程哲学。此外,延迟初始化还可能因为内存紧张的机器在一开始可以正常启动,而在需要并初始化某些bean后导致内存不够而崩溃,着同样会掩盖问题的发生。

因此,并不推荐积极地使用这项功能。

要开启延迟初始化,可以添加以下配置项:

spring.main.lazy-initialization=true

如果开启了延迟初始化,你希望某些自动注入的组件不被延迟初始化,可以使用@Lazy(false)注解:

@Service
@Lazy(false)
public class UserService implements UserServiceInterface {
	...
}

Banner

在应用启动后,你会在控制台看到这个:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.7)

这个叫做Banner(横幅),你可以用在资源目录中添加banner.txt的方式添加“自定义banner”:

=====================================================
This is my exampled spring boot app.
name:${application.title}
version:${application.formatted-version}
spring boot version:${spring-boot.formatted-version}
=====================================================

再运行你就可以看到类似这样的输出:

=====================================================
This is my exampled spring boot app.
name:
version:
spring boot version: (v2.6.7)
=====================================================

这里的${application.title}等都是banner中可以设置的相关参数,完整列表见Core Features (spring.io)

因为${application.title}这样的参数是从MANIFEST.MF获取的信息,所以直接从IDE运行是没法正常显示的,需要打包后运行jar包:

❯ java -jar .\target\my_first_app-0.0.1-SNAPSHOT.jar
=====================================================
This is my exampled spring boot app.
name:my_first_app
version: (v0.0.1-SNAPSHOT)
spring boot version: (v2.6.7)
=====================================================

你甚至可以通过添加banner.gifbanner.png等资源文件让应用打印一个图片作为banner,当然因为控制台的关系,这里打印的是转换为ASCII字符后的图片。

SpringApplication

可以通过SpringApplication以编程的方式修改某些配置,比如关闭banner:

package cn.icexmoon.my_first_app;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("cn.icexmoon.my_first_app.mapper")
public class MyFirstAppApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyFirstAppApplication.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }

}

再启动应用就会发现不显示banner了。

要了解可以通过SpringApplication修改的全部配置列表,可以阅读SpringApplication (Spring Boot 2.6.7 API)

命令行参数

可以通过注入ApplicationArguments对象的方式获取应用启动时的命令行参数:

package cn.icexmoon.my_first_app.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component;

@Component
public class ArgumentReader {
    @Autowired
    public ArgumentReader(ApplicationArguments args){
        if(args.containsOption("test")){
            System.out.println("test is find.");
            System.out.println(args.getNonOptionArgs());
        }
    }
}

打包后通过java -jar .\target\my_first_app-0.0.1-SNAPSHOT.jar --test hahaha.txt运行就会看到输出:

test is find.
[hahaha.txt]

要注意的是,为了让新添加的ArgumentReader组件被框架加载,需要关闭延迟初始化功能:

spring.main.lazy-initialization=false
  • 当然你可以可以使用@Lazy注解,不过为了方便后续代码演示,这里直接关闭延迟加载功能。
  • ArgumentReader构造器的@Autowired注解其实可以省略,因为在仅有一个构造器的情况下,框架会自动通过该构造器进行注入。

ApplicationRunner or CommandLineRunner

如果你有一些特殊代码需要在应用启动后执行,可以通过ApplicationRunnerCommandLineRunner接口实现,它们都有一个简单的run方法可以被覆盖,前者使用ApplicationArguments作为参数传递命令行参数,后者直接通过String[]传递。覆盖的run方法会在SpringApplication.run调用完成前被调用。

package cn.icexmoon.my_first_app.component;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class CommnadLineProcessor implements ApplicationRunner{
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("CommnadLineProcessor is triggered.");
        System.out.println(args.getSourceArgs());
    }
}

运行应用后会看到类似这样的输出:

CommnadLineProcessor is triggered.
[Ljava.lang.String;@559cf27

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值