loveqq-framework 作用域支持
singleton:单例作用域,整个应用上下文只有一个实例
prototype:原型作用域,有两种使用模式
1、不使用代理,该种模式下,每次获取都是一个新的实例,可用于对象级原型
2、代理模式,该种模式下,所有的注入都是同一个代理对象,可用于方法级别原型,方法调用结束后即销毁实例
refresh:刷新作用域,该作用域常用于配置类的实时更新,配置属性上下文更新的时候刷新实例
thread:线程作用域,java 线程的生命周期内有效,当线程销毁时,对应的 bean 自动执行销毁的生命周期
loveqq-framework 作用域刷新回调支持:ScopeRefreshed
当作用域刷新时,比如 @RefreshScope 刷新时,常规做法是将当前 bean 销毁,然后重新创建一个新的。
但是有些 bean 是有状态的,或者具有重量级初始化操作,不适合销毁重建。
此时 ScopeRefreshed 就派上了用场。
当 @RefreshScope 注解的 bean 需要刷新时,如果 bean 实现了 ScopeRefreshed 接口,则回调该接口,由开发者自身决定如何刷新,如果没有实现该接口,则依旧执行重建销毁流程。该逻辑同样适用于 @PrototypeScope / @ThreadScope。
下面是线程作用域的示例:
package com.kfyty.demo;
import com.kfyty.loveqq.framework.boot.K;
import com.kfyty.loveqq.framework.core.autoconfig.ApplicationContext;
import com.kfyty.loveqq.framework.core.autoconfig.DestroyBean;
import com.kfyty.loveqq.framework.core.autoconfig.InitializingBean;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.ThreadScope;
import com.kfyty.loveqq.framework.core.autoconfig.scope.ScopeRefreshed;
import com.kfyty.loveqq.framework.web.core.annotation.GetMapping;
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
import com.kfyty.loveqq.framework.web.core.autoconfig.annotation.EnableWebMvc;
import com.kfyty.loveqq.framework.web.core.request.support.ResponseBodyEmitter;
@EnableWebMvc
@RestController
@BootApplication
public class Main {
@Autowired
private DemoService service;
@GetMapping
public ResponseBodyEmitter scope() {
ResponseBodyEmitter emitter = new ResponseBodyEmitter();
new Thread(() -> {
emitter.send(service.current());
emitter.complete();
}).start();
return emitter;
}
@Component
@ThreadScope
public static class DemoService implements InitializingBean, DestroyBean, ScopeRefreshed {
private long s;
@Override
public void afterPropertiesSet() {
this.s = System.currentTimeMillis();
System.out.println("init demo service");
}
public String current() {
return String.valueOf(s);
}
@Override
public void onRefreshed(ApplicationContext applicationContext) {
s = System.currentTimeMillis();
System.out.println("refreshed demo service");
}
/**
* 线程运行结束后将自动执行该方法
*/
@Override
public void destroy() {
System.out.println("destroy demo service");
}
}
public static void main(String[] args) throws Exception {
K.run(Main.class, args);
}
}
上述代码,当访问 http://localhost:8080/scope 时,将返回当前的时间戳,因为每次都是新启线程执行。
当线程结束后,会回调 onRefreshed(ApplicationContext applicationContext) 接口,由开发者自身进行刷新。
当关闭容器时,会自动调用 destroy() 方法进行销毁。
感兴趣的同学可以了解下。