接下来我将一一讲述实现方式,这些操作的源码流程已经在启动过程总结一文中详细叙述过, 这里就只做定义解析和案例展示了,关于源码实现细节可跳转链接查看哈。
1. 使用 CommandLineRunner 和 ApplicationRunner
CommandLineRunner
和 ApplicationRunner
是 Spring Boot 提供的两个接口,用于在应用启动完成后执行逻辑。
CommandLineRunner
接收String[] args
参数,适合处理简单的启动参数。ApplicationRunner
接收ApplicationArguments
对象,方便解析复杂参数。
CommandLineRunner 示例:
java
代码解读
复制代码
import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("执行 CommandLineRunner 逻辑!"); for (String arg : args) { System.out.println("启动参数:" + arg); } } }
ApplicationRunner 示例:
java
代码解读
复制代码
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("执行 ApplicationRunner 逻辑!"); if (args.containsOption("debug")) { System.out.println("调试模式启动!"); } } }
适用场景: 在项目启动后立即执行初始化逻辑,例如加载缓存或注册服务。这是笔者比较推荐的方式,用的最多~~~
2. 使用 ApplicationListener 监听启动事件
Spring 提供了丰富的 事件机制。通过实现 ApplicationListener
接口,我们可以监听应用启动的各个阶段事件,如 ApplicationReadyEvent
。
示例:
typescript
代码解读
复制代码
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("应用启动完成,执行 ApplicationReadyEvent 事件监听逻辑!"); } }
适用场景: 当需要在应用完全启动后执行某些操作,如向监控系统注册实例。
3. 使用 @EventListener 注解
@EventListener
注解是一种简化的事件监听机制,允许我们用注解监听特定事件。
java
代码解读
复制代码
import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class MyEventListener { @EventListener(ApplicationStartedEvent.class) public void onApplicationStarted() { System.out.println("Spring Boot 启动时,执行 ApplicationStartedEvent 监听逻辑!"); } }
适用场景: 适用于监听特定事件,如应用启动或关闭时的操作。
上面使用监听事件的两种方式分别监听了事件ApplicationReadyEvent
和ApplicationStartedEvent
,同类型的事件如下所示,这里就不一一讲述了,感兴趣的可自行写写示例体会下。
项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用
Github地址:github.com/plasticene/…
Gitee地址:gitee.com/plasticene3…
微信公众号:Shepherd进阶笔记
交流探讨qun:Shepherd_126
4. 使用 @PostConstruct 注解
@PostConstruct
注解用于在 Bean 初始化完成后执行逻辑。这是一个标准的 Java 注解,Spring 会在依赖注入完成后调用它标注的方法。
示例:
kotlin
代码解读
复制代码
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Service public class MyService { @PostConstruct public void init() { System.out.println("Bean 初始化完成后执行 @PostConstruct 方法!"); } }
适用场景: 当需要在某个 Bean 初始化完成后执行逻辑,比如连接数据库、加载外部资源等。
5. 使用 BeanPostProcessor
BeanPostProcessor
接口允许我们在 Bean 初始化前后插入逻辑。
示例:
typescript
代码解读
复制代码
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; @Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化前处理 Bean:" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化后处理 Bean:" + beanName); return bean; } }
适用场景: 当需要对某些 Bean 的初始化过程进行增强时。
6. 使用 InitializingBean 接口
InitializingBean
接口中的 afterPropertiesSet()
方法会在 Bean 的属性设置完成后执行。
示例:
java
代码解读
复制代码
import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class MyInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("Bean 属性设置完成,执行 afterPropertiesSet() 方法!"); } }
适用场景: 当需要在 Bean 初始化后执行一些逻辑。
7. 使用 SmartInitializingSingleton 接口
SmartInitializingSingleton
是一个特殊接口,当 所有单例 Bean 初始化完成后,会触发 afterSingletonsInstantiated()
方法。
示例:
typescript
代码解读
复制代码
import org.springframework.context.SmartInitializingSingleton; import org.springframework.stereotype.Component; @Component public class MySmartInitializingSingleton implements SmartInitializingSingleton { @Override public void afterSingletonsInstantiated() { System.out.println("所有单例 Bean 初始化完成,执行 afterSingletonsInstantiated() 方法!"); } }
适用场景: 当需要确保所有单例 Bean 初始化完成后再执行操作。
8. 在 main 方法中执行逻辑
在 Spring Boot 应用的入口方法 main
中,我们也可以执行一些初始化逻辑。
示例:
typescript
代码解读
复制代码
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MyApplication { public static void main(String[] args) { System.out.println("Spring Boot 启动前,执行自定义逻辑!"); SpringApplication.run(MyApplication.class, args); System.out.println("Spring Boot 启动后,执行自定义逻辑!"); } }
适用场景: 当需要在应用启动的前后执行全局逻辑时。
总结
实现方式 | 触发时机 | 适用场景 |
---|---|---|
CommandLineRunner | 应用启动完成后 | 需要执行启动参数相关逻辑 |
ApplicationRunner | 应用启动完成后 | 更方便处理复杂启动参数 |
@PostConstruct | Bean 初始化完成后 | Bean 的初始化逻辑 |
ApplicationListener | 特定事件触发时 | 监听应用启动或关闭的事件 |
@EventListener | 特定事件触发时 | 使用注解简化事件监听 |
BeanPostProcessor | Bean 初始化前后 | 增强 Bean 的初始化过程 |
InitializingBean | Bean 属性设置完成后 | 属性注入后的初始化逻辑 |
SmartInitializingSingleton | 所有单例 Bean 初始化完成后 | 所有 Bean 完成初始化后的逻辑 |
main方法 | 应用启动前后 | 在应用启动前或启动后执行全局逻辑 |
选择合适的实现方式
- 需要在应用启动后立即执行逻辑:
CommandLineRunner
或ApplicationRunner
- 需要监听应用的启动事件:
ApplicationListener
或@EventListener
- 需要对 Bean 初始化过程进行控制:
@PostConstruct
或BeanPostProcessor
- 需要确保所有 Bean 初始化完成后再执行逻辑:
SmartInitializingSingleton
不同的实现方式适用于不同的场景,我们可以根据业务需求选择合适的方式,将逻辑插入到 Spring Boot 启动的不同阶段。