2016-06-12 11 views
1

Ich habe KlasseJersey 2 + HK2 - @ApplicationScoped funktioniert nicht

@ApplicationScoped 
public class Service{ 
private Map<String, Integer> something ; 
private final Logger LOGGER = LoggerFactory.getLogger(Service.class); 

@PostConstruct 
public void initialize(){ 
    something = new HashMap<>(); 
} 

public void increase(String userName){ 
    something.put(userName, something.getOrDefault(userName, 0) + 1); 
} 

public Map<String, Integer> getSomething(){ 
    return this.something; 
} 

public Integer getSomethingForUser(String userName){ 
    return something.getOrDefault(userName, 0); 
} 
} 

Was ich will global eine Instanz sein.

Das Problem ist, dass, wenn ich diesen Dienst an zwei verschiedenen Orten injiziere, habe ich zwei verschiedene Instanzen des Dienstes - die Ursachen, immer Zähler 0 zurückgeben. .toString() kehrt wie folgt:

[email protected] 
[email protected] 

habe ich diesen Dienst meine HK2-Jersey Implementierung zu testen, die offenbar nicht so sollte arbeiten.

Web.xml:

<servlet-name>jersey-serlvet</servlet-name> 
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>jersey.config.server.provider.packages</param-name> 
     <param-value>io.swagger.jaxrs.listing,mypackage.rest</param-value> 
    </init-param> 
    <init-param> 
     <param-name>jersey.config.server.provider.classnames</param-name> 
     <param-value> 
      io.swagger.jaxrs.listing.ApiListingResource, 
      io.swagger.jaxrs.listing.SwaggerSerializers 
     </param-value> 
    </init-param> 
    <init-param> 
     <param-name>javax.ws.rs.Application</param-name> 
     <param-value>mypackage.config.ApplicationConfiguration</param-value> 
     </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>jersey-serlvet</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
</servlet-mapping> 

ApplicationConfiguration.java:

public class ApplicationConfiguration extends ResourceConfig { 
public ApplicationConfiguration() { 
    register(new AbstractBinder() { 
     @Override 
     protected void configure() { 
      bind(Service.class).to(Service.class);  
     } 
    }); 

    packages(true, "com.mypackage.rest"); 
} 

}

Ohne diese bind Funktion Server wirft Ausnahme, dass @Inject nicht zufrieden war.

Kann jemand darauf hinweisen, was ist los?

Antwort

1

In HK2 gibt es keine @ApplicationScoped. Das ist nur CDI (was anders ist). In HK2 gibt es einen Singleton-Bereich. Mit Ihrer Konfiguration können Sie entweder

machen, was es automatisch zu einem Singleton macht. Das einzige Problem dabei ist, dass Sie jede Injektion durch den Behälter verlieren (falls Sie welche benötigen). Der andere Weg ist, den Umfang der in(Scope) Methode

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

einzustellen, dass javax.inject.Singleton ist.

+0

Danke, arbeitete wie ein Charme. Kannst du vielleicht sagen, ob es eine automatische Möglichkeit gibt, diese Klassen zu binden, oder ich sie manuell hinzufügen muss? – deem

+0

Wenn Sie eine weitere Frage stellen möchten, würde ich mich freuen, sie zu beantworten. –

+0

Ich denke, dass Jersey seine eigene Definition von @ApplicationScoped hat. Der Grund dafür, dass Sie verschiedene Instanzen gesehen haben, ist, dass es sich um einen Proxy-Bereich handelt und die injizierten Proxys daher unterschiedlich sind, selbst wenn die zugrundeliegenden tatsächlichen Services identisch sind (verwenden Sie equals und nicht == zum Vergleichen) – jwells131313