在 Micronaut 中有使用@PostConstruct 的正确方法吗?

Is there a proper way to use @PostConstruct in Micronaut?

我试图在使用 @PostConstruct 启动应用程序后打印一条消息,但没有打印任何内容。

package dev.renansouza.server;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}

我读到 @PostConstruct 是懒惰的。这是否意味着我需要做 还有什么可以让它起作用的吗?

https://github.com/jeffbrown/renansouzapostconstruct 查看项目。

https://github.com/jeffbrown/renansouzapostconstruct/blob/master/src/main/java/renansouzapostconstruct/ServerService.java

package renansouzapostconstruct;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}

https://github.com/jeffbrown/renansouzapostconstruct/blob/master/src/main/java/renansouzapostconstruct/DemoController.java

package renansouzapostconstruct;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.HttpStatus;

@Controller("/demo")
public class DemoController {

    private ServerService serverService;

    public DemoController(ServerService serverService) {
        this.serverService = serverService;
    }

    @Get("/")
    public HttpStatus index() {
        return HttpStatus.OK;
    }
}

当您启动应用程序时,您不会看到打印到标准输出的消息,因为服务 bean 尚未初始化。向 http://localhost:8080/demo/ 发送请求,然后您将看到打印到标准输出的消息。

希望对您有所帮助。

如果使用 @PostConstruct 对您来说不是那么重要,您也可以使用 @EventListener 注释来实现您想要的。

例如,在您的情况下,您可以在任何 class 中添加以下代码来侦听应用程序启动事件。

@EventListener
void onStartup(ServerStartupEvent event) {
    println("Hey, I work from anywhere in project..")
}

Code shared above is in Groovy

请记住,在主应用程序 class 中添加的事件侦听器通常首先被调用,据我观察。

正如您已经提到的,问题(又名功能)是延迟加载。

我看到两个解决方案:

  1. 您必须执行某些操作才能初始化该 bean。

  2. 将 bean 的范围从 @Singleton 更改为 @Context

Micronaut 有一些内置范围(参见 https://docs.micronaut.io/latest/guide/index.html#scopes) and the documentation of @Context states (see https://docs.micronaut.io/latest/api/io/micronaut/context/annotation/Context.html

Context scope indicates that the classes life cycle is bound to that of the BeanContext and it should be initialized and shutdown during startup and shutdown of the underlying BeanContext.

Micronaut by default treats all Singleton bean definitions as lazy and will only load them on demand. By annotating a bean with @Context you can ensure that the bean is loaded at the same time as the context.

package dev.renansouza.server;

import javax.annotation.PostConstruct;
import io.micronaut.context.annotation.Context;

@Context 
public class ServerService {

    @PostConstruct
    public void print() {
        System.out.println("Hello!");
    }
}