Dependency injection with Jersey 2.0

后端 未结 8 1098
遇见更好的自我
遇见更好的自我 2020-11-22 01:18

Starting from scratch without any previous Jersey 1.x knowledge, I\'m having a hard time understanding how to setup dependency injection in my Jersey 2.0 project.

8条回答
  •  清酒与你
    2020-11-22 02:01

    First just to answer a comment in the accepts answer.

    "What does bind do? What if I have an interface and an implementation?"

    It simply reads bind( implementation ).to( contract ). You can alternative chain .in( scope ). Default scope of PerLookup. So if you want a singleton, you can

    bind( implementation ).to( contract ).in( Singleton.class );
    

    There's also a RequestScoped available

    Also, instead of bind(Class).to(Class), you can also bind(Instance).to(Class), which will be automatically be a singleton.


    Adding to the accepted answer

    For those trying to figure out how to register your AbstractBinder implementation in your web.xml (i.e. you're not using a ResourceConfig), it seems the binder won't be discovered through package scanning, i.e.

    org.glassfish.jersey.servlet.ServletContainer
    
        jersey.config.server.provider.packages
        
            your.packages.to.scan
        
    
    

    Or this either

    
        jersey.config.server.provider.classnames
        
            com.foo.YourBinderImpl
        
    
    

    To get it to work, I had to implement a Feature:

    import javax.ws.rs.core.Feature;
    import javax.ws.rs.core.FeatureContext;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    public class Hk2Feature implements Feature {
    
        @Override
        public boolean configure(FeatureContext context) {
            context.register(new AppBinder());
            return true;
        }
    }
    

    The @Provider annotation should allow the Feature to be picked up by the package scanning. Or without package scanning, you can explicitly register the Feature in the web.xml

    
        Jersey Web Application
        org.glassfish.jersey.servlet.ServletContainer
        
            jersey.config.server.provider.classnames
            
                com.foo.Hk2Feature
            
        
        ...
        1
    
    

    See Also:

    • Custom Method Parameter Injection with Jersey
    • How to inject an object into jersey request context?
    • How do I properly configure an EntityManager in a jersey / hk2 application?
    • Request Scoped Injection into Singletons

    and for general information from the Jersey documentation

    • Custom Injection and Lifecycle Management

    UPDATE

    Factories

    Aside from the basic binding in the accepted answer, you also have factories, where you can have more complex creation logic, and also have access to request context information. For example

    public class MyServiceFactory implements Factory {
        @Context
        private HttpHeaders headers;
    
        @Override
        public MyService provide() {
            return new MyService(headers.getHeaderString("X-Header"));
        }
    
        @Override
        public void dispose(MyService service) { /* noop */ }
    }
    
    register(new AbstractBinder() {
        @Override
        public void configure() {
            bindFactory(MyServiceFactory.class).to(MyService.class)
                    .in(RequestScoped.class);
        }
    });
    

    Then you can inject MyService into your resource class.

提交回复
热议问题