Jersey 2 singleton dependency injection creates multiple instances

£可爱£侵袭症+ 提交于 2019-12-06 13:44:20

The getSingletons has nothing to do with injections. It is meant to register singleton JAX-RS components (i.e. resources classes and providers), which don't actually need to be "classic" singletons. They can just be an instance of a regular class.

To handle injection of arbitrary components/services with Jersey 2.x, see Custom Injection and Lifecycle Management.

The general pattern is to create a Factory<T> implementation, with T being the injectable type. Then the factory needs to be registered with the Jersey runtime. One way to do that is through an AbstractBinder. For example

public class MyContextProvider implements Factory<MyContext> {

    @Override
    public MyContext provide() {
        return new MyContext();
    }

    @Override
    public void dispose(Bar bar) {}
}

Then bind it in your subclass of ResourceConfig (which is a subclass of Application).

@ApplicationPath("/webresources")
public class AppConfig extends ResourceConfig {

    public AppConfig() {

        packages("com.stackoverflow.jersey");

        register(new AbstractBinder(){
            @Override
            protected void configure() {
                bindFactory(MyContextProvider.class)
                        .to(MyContext.class)
                        .in(Singleton.class);
            }
        });
    }
}

The packages method allows for scanning of the package and sub-packages for resource classes (classes annotated with @Path) and providers (classes annotated with @Provider), so you don't need to explicitly register them.

You will also need to make sure you have all the needed compile-time dependencies. If you are using Maven, just use

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.19</version>
    <scope>provided</scope>
</dependency> 

The provided scope is for if you are using Glassfish, as Glassfish alredy has the jars. You don't want to duplicate the jars with different version. If you are just in a servlet container like Tomcat, you can remove the <scope>. If you are not using Maven, then you need to add the jars manually from the Jersey JAX-RS 2.0 RI bundle. And likewise, if you are in Glassfish, you need to make the jars only compile-time jars. You do not want to include them into the build of the war.

Bfr

You can add this in your constructor :

if (instance == null)
   instance = this;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!