簡體   English   中英

JAX-RS依賴注入

[英]JAX-RS dependency injection

我使用Spring Rest完成了項目。 現在我們有一個小型休息項目,並計划與Jersey JAX-RS合作。 我是新手,並引用SO和其他博客來成功實現具有依賴注入的Rest api。

有以下代碼。

AppConfig.java

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class AppConfig extends Application {    
    @Override
    public Set<Class<?>> getClasses() {
        System.out.println("AppConfig");
        final Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(Controller.class);
        s.add(AppFeature.class);
        return s;
    }
}

AppBinder.java

import org.glassfish.hk2.utilities.binding.AbstractBinder;

public class AppBinder extends AbstractBinder {
    @Override
    protected void configure() {
        System.out.println("AppBinder");
        bind(ReflectionService.class).to(ReflectionService.class);
    }
}

AppFeature.java

import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;

public class AppFeature implements Feature {
    @Override
    public boolean configure(FeatureContext context) {
        System.out.println("AppFeature");
        context.register(new AppBinder());
        return true;
    }
}

Controller.java

@Path("/")
public class Controller {   
    @Inject
    Service service;    
    public Controller(){
        System.out.println("Controller created");
    }
    // other methods
}

Service.java

@Singleton
public class Service    
    public Service(){
        System.out.println("Service instance created");
    }
    // other methods
}

我假設在Tomcat 8服務器啟動時創建了Controller和Service的每個實例,並完成了依賴注入。 但在啟動期間,在控制台上得到了這個

信息:在servlet映射/ *上注冊名為com.sample.auto2.AppConfig的Jersey servlet應用程序,使用相同名稱的Application類。

AppConfig中

AppConfig中

2016年11月15日下午12:22:20 org.glassfish.jersey.server.ApplicationHandler初始化INFO:啟動Jersey應用程序,版本澤西:2.6 2014-02-18 21:52:53 ...

AppFeature

AppBinder

2016年11月15日下午12:22:21 org.apache.catalina.startup.HostConfig deployDirectory

每次 ,我們發送一個請求,在控制台中得到關注

已創建服務實例

控制器創建

我的問題

  1. 每當我們發送http請求時,都會調用服務,控制器構造函數; 它是在每個請求中創建實例還是只調用構造函數?
  2. 為什么AppConfig中的 System.out被調用兩次?
  3. 有沒有更好的方法來設置我的小項目,它沒有任何數據庫訪問權限,只有三個帖子端點?

編輯:

按照由@Harikrishnan提供的鏈接,加入@SingletonController類。 現在構造函數只調用一次( 在第一次請求時 - 為什么不在服務器啟動期間!!)。

但是為什么Service類構造函數調用每個請求(在將@Singleton添加到Controller之前),即使它是單例? 還有其他問題。

編輯2

謝謝@peeskillet。 所以這些都是我的結果。

  1. 這在第一次請求時只調用一次構造函數

     bind(ReflectionService.class).to(ReflectionService.class).in(Singleton.class); bind(Controller.class).to(Controller.class).in(Singleton.class); 
  2. 這給出了http請求的錯誤

     bind(ReflectionService.class).to(ReflectionService.class).in(Immediate.class); java.lang.IllegalStateException: Could not find an active context for org.glassfish.hk2.api.Immediate 

    但是沒關系,因為

  3. 這在服務器啟動時調用了構造函數,只有一次

     bind(new ReflectionService()).to(ReflectionService.class); bind(new Controller()).to(Controller.class); 
  4. 通過此,在啟動時完成注入,但在http請求上有404錯誤。 (思想控制器在AppBinder中配置,那么為什么在AppConfig中)

     @ApplicationPath("/") public class AppConfig extends ResourceConfig { public AppConfig() { register(new AppBinder()); } } 
  5. 正如你所說,這使它運行起來!

     @ApplicationPath("/") public class AppConfig extends ResourceConfig { public AppConfig() { register(new AppBinder()); register(Controller.class); } } 

最后這些都是我需要的

public class AppBinder extends AbstractBinder {
    @Override
    protected void configure() {
        bind(new ReflectionService()).to(ReflectionService.class);
        bind(new Controller()).to(Controller.class);
    }
}

@ApplicationPath("/")
public class AppConfig extends ResourceConfig  {    
    public AppConfig() {
        register(new AppBinder());
        register(Controller.class);
    }
}

每當我們發送http請求時,都會調用服務,控制器構造函數; 它是在每個請求中創建實例還是只調用構造函數?

不幸的是,使用AbstractBinder綁定時@Singleton沒有任何效果。 我們需要明確地說它應該是一個單身人士

bind(ReflectionService.class).to(ReflectionService.class).in(Singleton.class);

默認行為是“每個查找”范圍,這意味着每次請求服務時都會創建一個新實例

(在第一次請求時 - 為什么不在服務器啟動期間!!)

這是它的工作原理。 還有一個ImmediateScope ,它將導致它在啟動時創建

 bind(ReflectionService.class).to(ReflectionService.class).in(ImmediateScope.class)

或者您可以只使用實例而不是類,它將自動成為單例

bind(new ReflectionService()).to(ReflectionService.class)

每當我們發送http請求時,都會調用服務,控制器構造函數; 它是在每個請求中創建實例還是只調用構造函數?

這是默認行為。 每個請求的資源類的新實例。 如上所述,如果您只想要一次實例,則將其標記為@Singleton

為什么AppConfig中的System.out被調用兩次?

不確定,可能只需要在bootstrap上進行Jersey內部處理

有沒有更好的方法來設置我的小項目,它沒有任何數據庫訪問權限,只有三個帖子端點?

您的設置很好,但如果您使用的是Jersey,則應使用ResourceConfigApplication擴展名)類而不是Application

@ApplicationPath("/")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        register(new AppBinder());
        register(Controller.class);
    }
}

有了這個,您不需要在AppBinder中包裝AppFeature 澤西島已經知道如何處理AppBinder

默認情況下,Jersey為每個請求創建資源類的新實例。 因此,如果您不注釋Jersey資源類,它會隱式使用@RequestScoped范圍

請閱讀https://stackoverflow.com/a/20505899/721597

另外看看Jersey 2單例依賴注入會創建多個實例

暫無
暫無

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

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