泽西岛2单身依赖注入创建多个实例 [英] Jersey 2 singleton dependency injection creates multiple instances

查看:202
本文介绍了泽西岛2单身依赖注入创建多个实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这里有一个单身人士,我想注入到我的应用程序中

Here I have a singleton, that I whant to inject to my application

@Singleton
@Path("singleton-bean")
public class MyContext {

    private MyContext() {
        instances++;
    }

    private static MyContext instance;

    public static MyContext getInstance(){
        if (instance == null)
            instance = new MyContext();
        return instance;
    }

    public static int instances = 0;

}

这是我的注册方式:

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Object> getSingletons() {
        final Set<Object> singletons = new HashSet<>();
        singletons.add(MyContext.getInstance());
        return singletons;
    }

    //.....

最后,我在请求中打印单身人数:

Finally, I print the nuber of singletons in request:

@Path("foo")
public class Foo {

    @Inject
    public MyContext message;

    @GET
    public String index() throws UnknownHostException {
        return String.format("%s number of instances: %s", message, MyContext.instances);
    }

它返回两个实例.我知道Jersey使用反射来访问私有构造函数并创建另一个实例.为什么会发生这种情况,以及如何防止这种情况发生?

It returns two instances. I understand that Jersey uses reflections to access private constructor and create another instance. Why is this happening and how do I prevent this?

推荐答案

getSingletons与注入无关.它旨在注册单例JAX-RS组件(即资源类和提供者),而实际上并不需要是经典"单例.它们可以只是常规类的实例.

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.

要使用Jersey 2.x处理任意组件/服务的注入,请参见自定义注入和生命周期管理.

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

通常的模式是创建一个Factory<T>实现,其中T是可注入类型.然后,工厂需要在Jersey运行时中注册.一种方法是通过AbstractBinder.例如

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) {}
}

然后将其绑定到您的ResourceConfig子类(这是Application的子类)中.

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);
            }
        });
    }
}

packages方法允许扫描软件包和子软件包中的资源类(使用@Path注释的类)和提供程序(使用@Provider注释的类),因此您无需显式注册它们

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.

您还需要确保拥有所有必需的编译时依赖项.如果您使用的是Maven,则只需使用

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> 

provided范围适用于您是否使用Glassfish的情况,因为Glassfish alredy有罐子.您不想复制具有不同版本的罐子.如果您只是在像Tomcat这样的servlet容器中,则可以删除<scope>.如果您不使用Maven,则需要从 Jersey JAX-RS 2.0 RI软件包.同样,如果您在Glassfish中,则需要将jars设为仅编译时的jars.您不想将它们包括在战争中.

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.

这篇关于泽西岛2单身依赖注入创建多个实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆