Я пытаюсь интегрировать только Micronaut Dependency Injection в приложение, которое использует Vert.x. Чтобы сделать это, я бы хотел, чтобы у каждой Вертикали был свой BeanContext
с нужными им экземплярами. Для этого не Micronaut запускается, а запускается Vert.x / развертыватель Verticle.
Учитывая уровень контроля над DI и порядок, который требуется для этого, я использовал @Factory
, чтобы иметь один Vert. x экземпляр внедрен везде:
@Factory
public class SubConfig {
private final Vertx vertx;
private final Context context;
public SubConfig(Vertx vertx) {
this.vertx = vertx;
this.context = vertx.getOrCreateContext();
}
@Bean
@Singleton
public RedisClient redisClient() {
final JsonObject redisConfiguration = this.context.config().getJsonObject("redisConfiguration");
final RedisOptions redisOptions = new RedisOptions(redisConfiguration);
return RedisClient.create(this.vertx, redisOptions);
}
@Bean
@Singleton
public RouterFactory routerFactory(StatusEndpointHandler statusEndpointHandler) {
StatusEndpointDefinition statusEndpointDefinition = new StatusEndpointDefinition(statusEndpointHandler);
List<EndpointDefinition> endpointDefinitions = ImmutableList.of(statusEndpointDefinition);
Set<RoutesDefinition> routesDefinitions = new HashSet<>();
routesDefinitions.add(new SubstitutionsRoutes(endpointDefinitions));
return new RouterFactory(routesDefinitions, new HashSet<>());
}
}
, а затем, при запуске Verticle:
@Slf4j
public class SubVerticle extends AbstractVerticle {
private BeanContext beanContext;
public SubVerticle() {
// -- Should be constructor?? -- do not have access to this.vertx yet
//this.beanContext = BeanContext.run();
//this.beanContext.registerSingleton(new SubstitutionConfig(this.vertx), true);
}
@Override
public void start(final Future<Void> startFuture) {
// --- This is where the beans should be injected??
this.beanContext = BeanContext.run();
this.beanContext.registerSingleton(new SubstitutionConfig(this.vertx), true);
this.startHttpServer(startFuture);
}
private HttpServer httpServer() {
log.info("Setting up HTTP server");
final HttpServerOptions options = new HttpServerOptions();
final Router router = this.setupRouter();
server.requestHandler(router::accept);
return server;
}
private Router setupRouter() {
// Inline injection of routerFactory and endpoints setup
RouterFactory routerFactory = beanContext.getBean(RouterFactory.class);
routerFactory.useLoggerHandler(new LoggerHandler());
return routerFactory.globalRouter(this.vertx);
}
}
У меня есть в основном 2 вопроса:
Как могу ли я программно создать экземпляр @Factory
без использования аннотации, чтобы контролировать момент создания бинов? Я не нахожу метод с именем registerFactory
в BeanContext
, я использую registerSingleton
, но, похоже, он не вызывает весь цикл DI. Целью является полный контроль над тем, когда запускается жизненный цикл компонента, поэтому я могу внедрить экземпляр vertx
в нужную точку.
Это правильный подход использования Micronaut DI с Vert .Икс? Verticle в его start()
или конструкторе инициирует DI и получает бины как синглтоны в сам экземпляр Verticle, так что гарантии безопасности потока соблюдаются. Я следую этому руководству: https://medium.com/@taraskohut / vert-x-micronaut-do-we-Need-Need-Need-Need-зависимость-инъекция-в-микросервисы-мир-84e43b3b228e