Search code examples
javajersey-2.0hk2

Using custom factory HK2 DI with Jersey


I'm using the HK2 container in my Jersey application . I need to use my custom factory method to get the injected instance from the HK2 container. For example ,

// Here I declare the IOC binding.
public class ApplicationBinder extends AbstractBinder {
    @Override
    protected void configure() {
        bind(Logger.class).to(ILogger.class).in(Singleton.class);;       
        bind(MySqlRepository.class).to(IRepository.class).in(Singleton.class);
    }
}



 public class MyApplication extends ResourceConfig {
    public static ApplicationBinder binder ;
    public MyApplication () {
        binder = new ApplicationBinder();
        register(binder);
        packages(true, "com.myapplication.server");
    }
    }

Here is my code :

public class BusinessLogic

    {
        //@Inject
        //ILogger logger ; 

        //Instead 
        ILogger logger = DependencyResolver .resolve(ILogger.class) // resolve will get ILogger from HK2   container
    }

The reason I need to do this way is for sometimes , I allocate classes manually which has dependencies , so in this way each use of @Inject return null. For example, if I use new BusinessLogic() , then the logger with @Inject is null. I have to bind businesslogic also and use IOC in order to get the ILogge.

I need something like this:

public class DependencyResolver {    

    public static <T> T resolve(Class<T> beanClass){           
        return instance;
    }    
}

I need to use the DependencyResolver in order to get the instances I registered in MyApplication.

Any suggestions. Thanks in advance...


Solution

  • I'm not 100% sure what exactly you want to do, but ...

    I think you misunderstood AbstractBinder.bind(...) or bindings itself. Also, afaig you can't inject something into an instance which is not kinda managed component (like your BusinessLogic).

    See jersey.java.net - ioc for examples regarding your BusinessLogic. You may have a look at ComponentProvider and/or InjectableProvider

    For your ILogger I would suggest to create and bind a Factory like this:

    public class LoggerFactory implements Factory<ILogger> {
    
        // inject stuff here if you need (just an useless example)
        @Inject
        public LoggerFactory(final UriInfo uriInfo) {
            this.uriInfo = uriInfo;
        }
    
        @Override
        public ILogger provide() {
            // here you resolve you ilogger
            return MyLocator.resolve(ILogger.class);
        }
    
        @Override
        public void dispose(ILogger instance) {
            // ignore
        }
    
    }
    

    Bind Factory

    public class ApplicationBinder extends AbstractBinder {
        @Override
        protected void configure() {
            bindFactory(LoggerFactory.class).to(ILogger.class).in(PerLookup.class /* or other scopeAnnotation if needed */);
    
            // what's you Logger.class ? 
            // bind(Logger.class).to(ILogger.class).in(Singleton.class);      
            // bind(MySqlRepository.class).to(IRepository.class).in(Singleton.class);
        }
    }
    

    Hope this was helpful somehow. Maybe someone is willing to write something about Providers for your case.