簡體   English   中英

如何在Jersey 2中禁用依賴注入?

[英]How to Disable Dependency Injection in Jersey 2?

我不熟悉使用Jersey 2創建REST Web服務。我現在能夠得到一些簡單的案例,我正在進行“真正的”工作。

我創建自己的ResourceConfig實例,並使用Guice返回的REST控制器實例填充ResourceConfig實例:

<!-- language: lang-java -->
final ResourceConfig rc = new ResourceConfig();

//register an *instance* of a REST controller
rc.register(injector.getInstance(MyRestController.class));

請注意,由於這些REST控制器實例由Guice提供,因此實例將填充所有必需的依賴項,這些依賴項使用@Inject批注進行標記。

但是,當我運行上面的代碼來引導Jersey時,我看到如下錯誤:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(....

顯然,正在發生的事情是Jersey 試圖解決REST控制器實例上的@Inject依賴關系,因為它看到了與Guice相同的@Inject注釋。

我不希望澤西島做任何依賴注入。 我認為從Jersey到Guice有橋梁,但根據我在這里無法顯示的程序要求,我需要自己創建REST控制器實例並向Guice Injector詢問它們。

我的問題:如何在Jersey中禁用依賴注入?

我目前正在使用javax.inject.Inject注釋。 也許我可以使用com.google.inject.Inject注釋,認為Jersey不會查找這些注釋。 但是,我寧願只關閉澤西島的依賴注入。 我怎樣才能做到這一點?

謝謝!!

首先,您的解決方案:

public class GuiceJerseyManualBridge extends io.dropwizard.Application<Configuration> {

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        JerseyEnvironment jersey = environment.jersey();

        // create the Guice env and its dependencies
        Injector i = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                Map<String, String> props = new HashMap<>();
                props.put("testme", "Hello World Guice Inject Test");
                Names.bindProperties(binder(), props);
                bind(HelloResource.class).in(Singleton.class);
            }
        });

        // get instance

        HelloResource resourceInstance = i.getInstance(HelloResource.class);
        jersey.register(new AbstractBinder() {

            @Override
            protected void configure() {
                // teach jersey about your guice dependency 
                bind(resourceInstance).to(HelloResource.class);
            }
        });

        jersey.register(HelloResource.class); // register resource - jersey will discover this from the binding
    }

    @Override
    public void initialize(Bootstrap<Configuration> bootstrap) {
        super.initialize(bootstrap);
    }

    public static void main(String[] args) throws Exception {
        new GuiceJerseyManualBridge().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test2.yaml");
    }

    @Path("test")
    @Produces(MediaType.APPLICATION_JSON)
    public static class HelloResource {


        @Inject
        @Named("testme")
        private String testString;

        public HelloResource() {
            System.err.println("I am created now");
        }

        @GET
        @Path("test")
        public String test(String x) {
            return testString;
        }

    }

}

請忽略我的DropWizard設置。 它使用Jersey並使用Guice,因此注冊部分是相同的。

你在這里遇到兩個困境:

  1. Jersey DI將嘗試在您的對象中注入字段。 那是因為它沒有意識到已經有一個對象已經完成。 它假設它必須注入字段。

所以,我上面的解決方案做了以下事情:

將Guice豆綁定到平針織環境。 這將使球衣找到您創建的bean。 由於它綁定到澤西環境中,它不會嘗試重新初始化bean,而是將其視為完全有效的對象。 為此,您需要將Resource注冊為類參數(觸發jersey以搜索已注冊的bean,或者根據需要創建一個)

您可以做的另一個解決方案是將Injects移動到構造函數(通常是避免字段注入的好習慣)。 因為您注冊了一個對象,所以再次調用構造函數是非法的。 因此球衣不會嘗試任何注射(因為沒有做)

最后,我不知道您的要求是如何工作的,但您想要做的主要是手動創建Guice-Jersey Bridge。 以你演示的方式教你的豆子到球衣上的確是Guice-Jersey橋的作用,除了它修復了所有那些小邊緣的情況(就像你現在看到的那樣)。 強烈建議您實施該橋接器。

這個橋的作用實際上就是簡單地將bean的創建委托給guice。 這意味着它將(1)向一個實例請求guice然后自己創建一個(如果Guice沒有返回實例)。

Hiope有幫助,

干杯! 阿圖爾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM