Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey and HK2 ServiceLocator

Tags:

jersey

hk2

I'm trying to initialize some components in my Jersey application in the Application constructor (the thing that inherits from ResourceConfig) . It looks like this

public Application(@Context ServletContext context,
                   @Context ServiceLocator locator)...

When I try to use the locator at any point, I still can't create instances of things that I have registered in an AbstractBinder using the locator.create(MyThing.class) method.

I'm certain that they are bound correctly because they are injected properly into my resource classes via the @inject field annotation.

The difference is that the Jersey/HK2 framework is instantiating my resource classes (as expected, since they're in my package scan path), but I can not seem to leverage the ServiceLocator through code.

My ultimate goal is to have other non-jersey classes injected when they have the @Inject attribute, eg. I have a worker class that needs to be injected with the configured database access layer. I want to say

locator.Create(AWorker.class) 

and have it injected.

How do I get the real ServiceLocator that will inject everything I've already registered/bound with my Binder? (Or should I be using something other than ServiceLocator?)

like image 670
Bill Avatar asked Oct 15 '25 20:10

Bill


1 Answers

I am going to assume you are starting up a servlet and have a class extending org.glassfish.jersey.server.ResourceConfig and your bindings are correctly registered (e.g. using a Binder and registerInstances). If you then want to access the ServiceLocator in order to perform additional initialization, you have two choices:

One approach is to register a ContainerLifecycleListener (as seen here in this post):

// In Application extends ResourceConfig constructor
register(new ContainerLifecycleListener() {

        @Override
        public void onStartup(final Container container) {
            // access the ServiceLocator here
            final ServiceLocator serviceLocator = container.getApplicationHandler().getInjectionManager().getInstance(ServiceLocator.class);

            // Perform whatever with serviceLocator
        }

        @Override
        public void onReload(final Container container) {
            /* ... */}

        @Override
        public void onShutdown(final Container container) {
            /* ... */}
    });

The second approach is to use a Feature, which can also be auto-discovered using @Provider:

@Provider
public final class StartupListener implements Feature {

    private final ServiceLocator sl;

    @Inject
    public ProvisionStartupListener(final ServiceLocator sl) {
        this.sl = sl;
    }

    @Override
    public boolean configure(final FeatureContext context) {
        // Perform whatever action with serviceLocator
        return true;
    }
like image 62
sfiss Avatar answered Oct 19 '25 13:10

sfiss



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!