类型 | 描述 |
---|---|
@Singleton | Singleton作用域表示只有一个Bean的实例会存在 |
@Context | Context作用域表示Bean将与ApplicationContext同时创建(eager initialization)。 |
@Prototype | 原型作用域表示每次注入Bean时都会创建一个新的实例。 |
@Infrastructure | 基础设施作用域表示一个不能被重写或使用@Replaces替换的Bean,因为它对系统的运行至关重要。 |
@ThreadLocal | @ThreadLocal 作用域是一个自定义作用域,它通过ThreadLocal为每个线程关联一个Bean。 |
@Refreshable | @Refreshable 作用域是一个自定义的作用域,它允许通过 /refresh 端点来刷新 bean 的状态。 |
@RequestScope | @RequestScope作用域是一个自定义作用域,它表示Bean的一个新实例被创建并与每个HTTP请求相关联。 |
@Prototype注解是@Bean的同义词,因为默认作用域是prototype。
可以通过定义一个实现CustomScope接口的@Singleton bean来添加额外的作用域。
请注意,在启动ApplicationContext时,默认情况下,@Singleton范围的Bean会被懒散地按需创建。这是为优化启动时间而设计的。
如果这对你的用例来说是个问题,你可以选择使用@Context注解,将你的对象的生命周期与ApplicationContext的生命周期绑定在一起。换句话说,当ApplicationContext启动时,你的Bean将被创建。
另外,用@Parallel注解任何@Singleton范围的Bean,它允许并行初始化你的Bean而不影响整体启动时间。
如果你的Bean未能并行初始化,应用程序将被自动关闭。
在某些情况下,@Singleton Bean的Eager 初始化可能是可取的,例如在AWS Lambda上,更多的CPU资源被分配给Lambda构建而不是执行。
你可以使用ApplicationContextBuilder接口指定是否Eager初始化@Singleton范围的Bean。
public class Application {
public static void main(String[] args) {
Micronaut.build(args)
.eagerInitSingletons(true)
.mainClass(Application.class)
.start();
}
}
将eager init设置为true可以初始化所有的singletons。
当你在诸如无服务器Functions的环境中使用Micronaut时,你将不会有一个Application类,而是扩展一个Micronaut提供的类。在这些情况下,Micronaut提供了一些方法,你可以重写这些方法来增强ApplicationContextBuilder的功能。
public class MyFunctionHandler extends MicronautRequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
...
@Nonnull
@Override
protected ApplicationContextBuilder newApplicationContextBuilder() {
ApplicationContextBuilder builder = super.newApplicationContextBuilder();
builder.eagerInitSingletons(true);
return builder;
}
...
}
@ConfigurationReader Bean,如@EachProperty或@ConfigurationProperties是singleton Bean。要想Eager初始化配置,同时保持其他@Singleton范围的Bean的懒惰初始化,请使用eagerInitConfiguration。
public class Application {
public static void main(String[] args) {
Micronaut.build(args)
.eagerInitConfiguration(true)
.mainClass(Application.class)
.start();
}
}
Refreshable 作用域是一个自定义作用域,它允许通过以下方式刷新 bean 的状态。
@Refreshable
public static class WeatherService {
private String forecast;
@PostConstruct
public void init() {
forecast = "Scattered Clouds " + new SimpleDateFormat("dd/MMM/yy HH:mm:ss.SSS").format(new Date());//
}
public String latestForecast() {
return forecast;
}
}
WeatherService被注解了@Refreshable范围,它存储了一个实例,直到触发了一个刷新事件。
当Bean被创建时,预测属性的值被设置为一个固定值,在Bean被刷新之前不会发生变化。
如果你调用 latestForecast() 两次,你会看到相同的响应。
当调用/refresh端点或发布RefreshEvent时,该实例会失效,并在下次请求该对象时创建一个新的实例。
比如说,
applicationContext.publishEvent(new RefreshEvent());
可以在Meta Annotations(元注解)上定义作用域,然后将其应用于你的类。
import io.micronaut.context.annotation.Requires;
import jakarta.inject.Singleton;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
// 该范围使用Requires声明了对一个Car类的需求
@Requires(classes = Car.class)
@Singleton
@Documented
@Retention(RUNTIME)
public @interface Driver {
}
@Singleton 注解被应用到 @Driver 注解上,这导致每个被 @Driver 注解的类都被看作是单例。
注意,在这种情况下,当注解被应用时,不可能改变范围。例如,下面的内容不会覆盖 @Driver 所声明的作用域,是无效的。
声明另一个作用域,
@Driver
@Prototype
class Foo {}
为了使作用域可被覆盖,请在 @Driver 上使用 DefaultScope 注解,它允许在没有其他作用域时指定一个默认的作用域。
@Requires(classes = Car.class)
@DefaultScope(Singleton.class)
@Documented
@Retention(RUNTIME)
public @interface Driver {
}
完结!