Как программно создать Фабрику в Micronaut для интеграции с Vert.x - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь интегрировать только 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

...