инъекция Джерси AbstractBinder не вызывает настроить - PullRequest
1 голос
/ 21 апреля 2019

Ответ:

Большое спасибо всем, кто смотрел на это, но особенно @Andbdrew.На основании его помощи у меня все работает, код на https://github.com/dabraham02124/injection/tree/feature.Я собираюсь выяснить, смогу ли я сделать так, чтобы аннотации «творили магию», и фактически заставлять код вызывать другой код, но он работает над веткой «feature».


Оригинальный вопрос:

Я пытаюсь внедрить ресурс в приложение jersey 2.7.Это не работаетЯ получаю следующую ошибку:

2019-04-20 22: 06: 06,004 WARN [qtp1142020464-16] oejsServletHandler - javax.servlet.ServletException: MultiException имеет 3 исключения.Это: 1. org.glassfish.hk2.api.UnsatisfiedDependencyException: не было объектов, доступных для инъекции в Injectee (requiredType = StringHolder, parent = EntryPoint, qualifiers = {}), position = -1, необязательно = false, self =false, unqualified = null, 1295211193) 2. java.lang.IllegalArgumentException: при попытке устранить зависимости ошибок org.sweatshop.injection.EntryPoint 3. java.lang.IllegalStateException: Невозможно выполнить операцию: разрешить в org.sweatshop.injection.EntryPoint

Я следовал всему, например, во всех уроках, например, но не ограничиваясь этим;

Я пытался добавлять различные аннотации в разных местах, я прочитал все страницы, которые я мог найти с помощью stackoverflowв этом я не вижу ничего изменяющегося.

Минимальный пример можно найти по https://github.com/dabraham02124/injection.Первый коммит не имеет инъекции, и он работает.Второй коммит имеет инъекцию и выбрасывает.

Для тех, кто хочет увидеть код на этой странице, вот биты, которые я считаю важными:

Класс ресурса

@Path("/")
@RequestScoped
public class EntryPoint {
    @Inject
    public StringHolder stringHolder;

    @GET
    @Produces(MediaType.TEXT_HTML)
    public Response homePage() {
        return Response.ok(stringHolder.getString()).build();
    }
}

Класс приложения

@ApplicationPath("/")
public class App extends ResourceConfig {
    private final MyServer jettyServer;
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);

    public App(MyServer jettyServer) {
        this.jettyServer = jettyServer;
    }

    public static void main(String[] args) throws Exception {
        final ServletContextHandler context = getContext();
        final MyServer jettyServer = new MyServer(8080, context);
        prepJettyServlet(context);

        log.info("about to start up");
        new App(jettyServer).runServer();
    }

    private void register() {
        log.info("start register");

        register(EntryPoint.class);
        register(StringHolder.class);
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                log.info("start bind singleton"); //These three lines never get called
                bind(new StringHolder("injected string")).to(StringHolder.class);
                log.info("end bind singleton");
            }
        });

        log.info("end register");
    }

Инжектированный класс синглтона

@RequestScoped
public class StringHolder {

    private final String string;

    public StringHolder(String string) {
        this.string = string;
    }

    public String getString() {
        return string;
    }
}

Интересно, что в журнале отображается регистр вызовов в Binder, но я никогда не вижу доказательств того, что configure вызывается.

Помогите?Я вырываю волосы и уже лысый ...

1 Ответ

1 голос
/ 22 апреля 2019

Вы можете использовать Feature, чтобы выполнить это, как отмечено в в этом ответе (я не мог сделать их первый подход с вашей версией трикотажа).

@Provider
public final class StartupListener implements Feature {

    private final ServiceLocator serviceLocator;

    @Inject
    public StartupListener(ServiceLocator serviceLocator) {
        this.serviceLocator = serviceLocator;
    }

    @Override
    public boolean configure(FeatureContext context) {
        ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
            @Override
            protected void configure() {
                bind(new StringHolder("injected string")).to(StringHolder.class);
            }
        });
        return true;
    }
}
...