Java项目启动时执行指定方法的几种方式

Spring启动时执行方法的三种方式
部署运行你感兴趣的模型镜像

很多时候我们都会碰到需要在程序启动时去执行的方法,比如说去读取某个配置,预加载缓存,定时任务的初始化等。这里给出几种解决方案供大家参考。

1. 使用@PostConstruct注解

这个注解呢,可以在Spring加载这个类的时候执行一次。来看一下下方代码。

 
@Component
public class Test {
		
        public Test(){
        	System.out.println("我最先执行");
        }
        
        /**
        *我第二个执行
        */
        @Autowired
        private T t;
        
    	/**
        *我第三个个执行
        */
    	@PostConstruct
    	private void init(){
    		//假装有代码
    	}
 }

上方就是@PostConstruct注解的使用方法了,同时也表示了此类被加载时的执行顺序。

2. CommandLineRunner接口

使用CommandLineRunner接口类似于Main方法启动,可以接受一个字符串数组的命令行参数,来看一下实现

 
@Component
public class MyCommandLineRunner implements CommandLineRunner{

    @Override
    public void run(String... args) throws Exception{
        //假装有代码
    }
}

3. ApplicationRunner 接口

此种方式与实现CommandLineRunner接口的区别就是他的参数是ApplicationArguments

 
@Order(value = 1)
@Component
public class MyApplicationRunner implements ApplicationRunner{

    @Override
    public void run(ApplicationArguments args) throws Exception{
        //假装有代码
    }
}

我们可以看到,此类相比较于第二种方式还增加一个@Order注解,这个注解其实第二种方式也是能加的。

它的作用就是控制类的加载顺序,这个顺序是从小到大的。比如说启动时先去加载Order的value等于1的类,然后去加载等于2的类。

本文出自http://zhixiang.org.cn,转载请保留。

您可能感兴趣的与本文相关的镜像

Langchain-Chatchat

Langchain-Chatchat

AI应用
Langchain

Langchain-Chatchat 是一个基于 ChatGLM 等大语言模型和 Langchain 应用框架实现的开源项目,旨在构建一个可以离线部署的本地知识库问答系统。它通过检索增强生成 (RAG) 的方法,让用户能够以自然语言与本地文件、数据库或搜索引擎进行交互,并支持多种大模型和向量数据库的集成,以及提供 WebUI 和 API 服务

### 协程在 Java Android 中的启动方式 Kotlin 协程为 Android 开发提供了结构化并发的机制,使得异步任务的管理更加高效和安全。虽然 Java 不直接支持协程语法,但可以通过 Kotlin 编写的协程接口与 Java 代码交互。以下是 Java Android 中启动协程的几种方式: #### 1. 使用 `GlobalScope` 启动协程 `GlobalScope` 不绑定任何生命周期,适用于全局任务。使用 `GlobalScope.launch` 启动的协程不会受到 Android 生命周期的限制,但需要注意内存泄漏问题。 ```java import kotlin.Unit; import kotlin.coroutines.CoroutineContext; import kotlinx.coroutines.*; public class CoroutineExample { public static void startGlobalScopeCoroutine() { GlobalScope.INSTANCE.launch((CoroutineContext)null, (CoroutineStart)null, new suspend() { @Override public Object invokeSuspend(Object result) { // 协程逻辑 System.out.println("GlobalScope 协程执行"); return Unit.INSTANCE; } }); } } ``` #### 2. 使用 `lifecycleScope` 启动协程 `lifecycleScope` 与 `Activity` 或 `Fragment` 的生命周期绑定,适用于 UI 相关任务。在 Java 中,可以通过 Kotlin 编写的扩展函数访问 `lifecycleScope`。 ```java import androidx.lifecycle.LifecycleOwner; import kotlinx.coroutines.*; public class LifecycleScopeExample { public static void startLifecycleScope(LifecycleOwner lifecycleOwner) { lifecycleOwner.getLifecycleScope().launch((CoroutineContext)null, (CoroutineStart)null, new suspend() { @Override public Object invokeSuspend(Object result) { // 协程逻辑 System.out.println("lifecycleScope 协程执行"); return Unit.INSTANCE; } }); } } ``` #### 3. 使用 `viewModelScope` 启动协程 `viewModelScope` 与 `ViewModel` 生命周期绑定,适用于执行与 UI 无关的后台任务。Java 中可以通过 Kotlin 编写的 `ViewModel` 调用 `viewModelScope.launch`。 ```java import androidx.lifecycle.ViewModel; import kotlinx.coroutines.*; public class MyViewModel extends ViewModel { public void startViewModelScope() { getViewModelScope().launch((CoroutineContext)null, (CoroutineStart)null, new suspend() { @Override public Object invokeSuspend(Object result) { // 协程逻辑 System.out.println("viewModelScope 协程执行"); return Unit.INSTANCE; } }); } } ``` #### 4. 使用 `repeatOnLifecycle` 控制协程执行时机 `repeatOnLifecycle` 确保协程只在特定生命周期状态下执行,避免在非活跃状态更新 UI。Java 中可以通过 Kotlin 编写的 `repeatOnLifecycle` 扩展函数调用。 ```java import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import kotlinx.coroutines.*; public class RepeatOnLifecycleExample { public static void startRepeatOnLifecycle(LifecycleOwner lifecycleOwner) { lifecycleOwner.getLifecycleScope().launch((CoroutineContext)null, (CoroutineStart)null, new suspend() { @Override public Object invokeSuspend(Object result) { BuildersKt.repeatOnLifecycle(lifecycleOwner.getLifecycle(), Lifecycle.State.STARTED, (CoroutineContext)null, new suspend() { @Override public Object invokeSuspend(Object result) { // 协程逻辑 System.out.println("repeatOnLifecycle 协程执行"); return Unit.INSTANCE; } }); return Unit.INSTANCE; } }); } } ``` #### 5. 使用 `withContext` 切换线程 `withContext` 函数内部会挂起协程,切换到指定的线程池执行任务,任务完成后再恢复协程 [^3]。Java 中可以通过 Kotlin 协程库调用 `withContext`。 ```java import kotlinx.coroutines.*; public class WithContextExample { public static void startWithContext() { GlobalScope.INSTANCE.launch((CoroutineContext)null, (CoroutineStart)null, new suspend() { @Override public Object invokeSuspend(Object result) { BuildersKt.withContext(Dispatchers.getIO(), new suspend() { @Override public Object invokeSuspend(Object result) { // 执行 I/O 操作 System.out.println("IO 线程执行"); return Unit.INSTANCE; } }, (Continuation<? super Object>) null); return Unit.INSTANCE; } }); } } ``` --- ### 协程启动方式的区别 - **GlobalScope**:适用于全局任务,不绑定生命周期,但需注意内存泄漏问题 [^1]。 - **lifecycleScope**:适用于与 UI 交互的任务,生命周期绑定到 `Activity` 或 `Fragment` [^1]。 - **viewModelScope**:适用于与 UI 无关的后台任务,生命周期绑定到 `ViewModel` [^1]。 - **repeatOnLifecycle**:确保协程仅在特定生命周期状态下执行,避免非活跃状态更新 UI [^3]。 - **withContext**:用于切换线程,执行 I/O 或 CPU 密集型任务 [^3]。 --- ### 最佳实践 - 避免在 `GlobalScope` 中启动协程,防止内存泄漏 [^1]。 - 使用 `repeatOnLifecycle` 控制协程执行时机,确保只在活跃状态下执行 UI 操作 [^3]。 - 合理选择调度器,I/O 操作使用 `Dispatchers.IO`,UI 操作使用 `Dispatchers.Main` [^3]。 - 使用 `CoroutineExceptionHandler` 捕获未处理异常,避免程序崩溃 [^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值