图源:
我们的Spring Boot
应用是通过SpringApplication.run
启动的,启动后可以看到控制台输出欢迎信息以及一些日志信息,如果失败,也会显示相应的错误信息。
SpringApplication
的主要工作是加载相关的配置,创建Web
应用的上下文,以及启动应用等。
下面介绍和SpringApplication
相关的Spring Boot
特性。
本篇文章的演示代码基于修改而来,你可以从相应的链接获取。
Lazy Initialization
Lazy Initialization
也可以叫做“延迟初始化”或“懒加载”,这是一个常用的Web
技术,比如大量图片的展示网页,就会在用户下滑需要展示相应图片时再真正加载图片资源,这可以节省一开始网页加载的时间和带宽。
在Sprint Boot
中,这指的是可以将相关创建和注入bean
的行为延后到真正需要这些bean
的时候,这样做可以加快应用的启动速度。但缺点是如果bean
的生成会产生bug
,那么就无法在一开始应用启动时暴露,而是延后到使用bean
时,这样就违背了“尽可能早地暴露bug”这条编程哲学。此外,延迟初始化还可能因为内存紧张的机器在一开始可以正常启动,而在需要并初始化某些bean
后导致内存不够而崩溃,着同样会掩盖问题的发生。
因此,并不推荐积极地使用这项功能。
要开启延迟初始化,可以添加以下配置项:
spring.main.lazy-initialization=true
如果开启了延迟初始化,你希望某些自动注入的组件不被延迟初始化,可以使用@Lazy(false)
注解:
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
中可以设置的相关参数,完整列表见。
因为${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.gif
、banner.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;
"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
修改的全部配置列表,可以阅读。
命令行参数
可以通过注入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;
public class ArgumentReader {
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
如果你有一些特殊代码需要在应用启动后执行,可以通过ApplicationRunner
或CommandLineRunner
接口实现,它们都有一个简单的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;
public class CommnadLineProcessor implements ApplicationRunner{
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
参考资料
文章评论