跳转到内容

生命周期

在 Feat Cloud 中对于托管的实例的生命周期管理可分为:创建 -> 属性填充 -> 初始化 -> 使用 -> 销毁 几个核心阶段。下图直观展示了 Bean 的完整生命周期流程:

Feat Cloud 生命周期

创建实例

Feat Cloud 通过 @Bean@Controller 注解来定义实例对象。

方式1

在某个 class 上添加注解 @Bean。Feat Cloud 启动时会自动创建该 Bean,bean 的名称默认为类名首字母小写。

@Bean
public class BeanDemo{
}

如果需要自定义 bean 的名称,可以通过 value 属性来指定。例如:@Bean(“beanDemo2”)

@Bean("beanDemo2")
public class BeanDemo{
}

@Controller 是一种特殊的 Bean,它没有 bean 名称的概念。 我们认为一个 Controller 的核心功能就是提供 HTTP 服务,而不是成一个可被外部依赖的 bean 对象。

@Controller
public class ControllerDemo{
}

方式2

在 Bean/Controller 的中通过 @Bean 注解定义 Bean 方法。 若未在 @Bean 中指定 bean 的名称,则默认为方法名。

@Bean
public class BeanDemo{
@Bean
public BeanDemo beanDemo2(){
return new BeanDemo();
}
}

方式3

服务启动时通过addExternalBean方法添加外部 Bean。

public class FeatCloudDemo {
public static void main(String[] args) {
Feat.cloudServer(opts -> opts.addExternalBean("beanDemo", new BeanDemo()))
.listen();
}
}

注意:@Autowired、@PostConstruct、@PreDestroy 等注解的相关特性不在此类 Bean 中生效。

@Autowired:属性填充

该注解用于填充 Bean 或者 Controller 的属性,类似于 Spring 中的 @Autowired

注意:因为技术方面的原因,现阶段需要显示提供属性的 setter 方法。

@Bean
public class FeatBeanDemo {
@Autowired
private String hello;
public static void main(String[] args) {
Feat.cloudServer(opts -> opts.addExternalBean("hello", "你好~")).listen();
}
public void setHello(String hello) {
this.hello = hello;
}
}

@PostConstruct:初始化

同 Spring 中的 @PostConstruct 注解,在 Bean 完成实例化和属性填充后被调用。

@Bean
public class FeatBeanDemo {
@Autowired
private String hello;
@PostConstruct
public void init() {
System.out.println(hello);
}
public static void main(String[] args) {
Feat.cloudServer(opts -> opts.addExternalBean("hello", "你好~")).listen();
}
public void setHello(String hello) {
this.hello = hello;
}
}

使用 Bean

在 Feat Cloud 中,可以通过 @Autowired 注解来注入和使用其他 Bean。Bean 之间可以相互依赖,形成依赖关系图。

@Bean
public class BeanDemo {
@Autowired
private OtherBean otherBean;
public void useOtherBean() {
// 使用注入的 otherBean
otherBean.doSomething();
}
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
}
@Bean
public class OtherBean {
public void doSomething() {
System.out.println("OtherBean is doing something");
}
}

循环依赖

Feat Cloud 支持 Bean 之间的循环依赖。当两个或多个 Bean 相互依赖时,Feat Cloud 能够正确处理这种情况,确保所有 Bean 都能正确初始化。

@Bean
public class BeanA {
@Autowired
private BeanB beanB;
public void setBeaB(BeanB beanB) {
this.beanB = beanB;
}
}
@Bean
public class BeanB {
@Autowired
private BeanA beanA;
public void setBeanA(BeanA beanA) {
this.beanA = beanA;
}
}

Bean 的作用域

目前 Feat Cloud 中的 Bean 默认都是单例的,即在整个应用中只有一个实例。这意味着无论在哪里注入这个 Bean,获取到的都是同一个实例。

@PreDestroy:销毁

@PreDestroy 作用于 Bean 或者 Controller 内部 public 方法上,类似于 Spring 中的 @PreDestroy。当应用关闭时,Feat Cloud 会调用标记了 @PreDestroy 注解的方法,以便 Bean 可以释放资源或执行其他清理操作。

@Bean
public class ResourceBean {
private Resource resource;
@PostConstruct
public void init() {
// 初始化资源
resource = new Resource();
System.out.println("资源已初始化");
}
@PreDestroy
public void destroy() {
// 释放资源
if (resource != null) {
resource.close();
System.out.println("资源已释放");
}
}
// 资源类示例
private class Resource {
public void close() {
// 关闭资源的逻辑
}
}
}

销毁时机

当以下情况发生时,@PreDestroy 注解的方法会被调用:

  1. 应用正常关闭时(如调用 System.exit()
  2. 通过 JVM 的 shutdown hook 关闭应用时
  3. 在 Feat Cloud 中,当调用 server.shutdown() 方法时