<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (c) 2013, 2024 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents;]>
<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="ioc">
    <title>Custom Injection and Lifecycle Management</title>

    <para>
        Since version 2.0, Jersey uses &hk2.link; library for component life cycle management and dependency injection.
        Rather than spending a lot of effort in maintaining Jersey specific API (as it used to be before Jersey 2.0 version),
        Jersey defines several extension points where end-user application can directly manipulate Jersey HK2 bindings
        using the HK2 public API to customize life cycle management and dependency injection of application components.
    </para>

    <para>
        Jersey user guide can by no means supply an exhaustive documentation of HK2 API in its entire scope.
        This chapter only points out the most common scenarios related
        to dependency injection in Jersey and suggests possible options to implement these scenarios.
        It is highly recommended to check out the &hk2.link; website and read HK2 documentation in order to get
        better understanding of suggested approaches. HK2 documentation should also help in resolving use cases
        that are not discussed in this writing.
    </para>

    <para>
        There are typically three main use cases, where your application may consider dealing with
        HK2 APIs exposed in Jersey:

        <itemizedlist>
            <listitem><simpara>Implementing a custom injection provider that allows an application to define
                additional types to be injectable into Jersey-managed JAX-RS components.</simpara></listitem>
            <listitem><simpara>Defining a custom injection annotation (other than &jee6.javax.inject.Inject;
                or &jaxrs.core.Context;) to mark application injection points.</simpara></listitem>
            <listitem><simpara>Specifying a custom component life cycle management for your application
                components.</simpara></listitem>
        </itemizedlist>
    </para>

    <para>
        Since Jersey 2.26, the injection has been abstracted, so that &hk2.link; can be eventually replaced by the CDI or
        any other injection framework. In the next chapters, we document possibilities provided directly by &hk2.link; and
        by Jersey abstraction components.
    </para>

    <section xml:id="injection.manager">
        <title>InjectionManager</title>

        <para>
            Since Jersey 2.26, Jersey comes with the main abstraction interface to communicate with the DI container, the
            &jersey.common.internal.inject.InjectionManager;. What is <literal>ServiceLocator</literal> for &hk2.link;, or
            <literal>BeanManager</literal> for CDI, that's &jersey.common.internal.inject.InjectionManager; for Jersey.
        </para>
        <para>
            &jersey.common.internal.inject.InjectionManager; can be injected into the user provided classes instantiated
            by Jersey. It can also be obtained programmatically by &jersey.client.InjectionManagerClientProvider;
            and &lit.jersey.common.InjectionManagerProvider; from Jakarta REST components, such as
            &jaxrs.core.FeatureContext;, or &jaxrs.ext.MessageBodyReader; and &jaxrs.ext.MessageBodyReader;.
        </para>
        <para>
            Customers used to the &hk2.ServiceLocator; can still use it directly; the &hk2.ServiceLocator; can be obtained
            either directly by injection, or programmatically as <literal>InjectionManager.getInstance(ServiceLocator.class)</literal>.
        </para>
    </section>

    <section>
        <title>Implementing Custom Injection Provider</title>

        <para>
            Relying on Servlet HTTP session concept is not very RESTful. It turns the originally state-less HTTP
            communication schema into a state-full manner. However, it could serve
            as a good example that will help me demonstrate implementation of the use cases described above.
            The following examples should work on top of Jersey Servlet integration module. The approach that will be
            demonstrated could be further generalized.
            Below we will show how to make actual Servlet &jee6.servlet.HttpSession; injectable into JAX-RS components
            and how to make this injection work with a custom inject annotation type. Finally, we will demonstrate
            how you can write &lit.jee6.servlet.HttpSession;-scoped JAX-RS resources.
        </para>

        <para>
            Jersey implementation allows you to directly inject &jee6.servlet.HttpServletRequest; instance into
            your JAX-RS components.
            It is quite straight forward to get the appropriate &lit.jee6.servlet.HttpSession; instance out of the
            injected request instance.
            Let say, you want to get &lit.jee6.servlet.HttpSession; instance directly injected into your JAX-RS
            types like in the code snippet below.

            <programlisting language="java">@Path("di-resource")
public class MyDiResource {

    @Inject HttpSession httpSession;

    ...

}</programlisting>
        </para>
        <section>
            <title>Using HK2 classes</title>

            <para>
            To make the above injection work, you will need to define an additional HK2 binding in your
            application &jersey.server.ResourceConfig;.
            Let's start with a custom HK2 &hk2.Factory; implementation that knows how to extract
            &lit.jee6.servlet.HttpSession; out of given &lit.jee6.servlet.HttpServletRequest;.

            <programlisting language="java">import org.glassfish.hk2.api.Factory;
    ...

    public class HttpSessionFactory implements Factory&lt;HttpSession&gt; {

    private final HttpServletRequest request;

    @Inject
    public HttpSessionFactory(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public HttpSession provide() {
       return request.getSession();
    }

    @Override
    public void dispose(HttpSession t) {
    }
}</programlisting>

            Please note that the factory implementation itself relies on having the actual
            &lit.jee6.servlet.HttpServletRequest; instance injected.
            In your implementation, you can of course depend on other types (and inject them conveniently)
            as long as these other types are bound to the actual HK2 service locator by Jersey or by your
            application. The key notion to remember here is that your HK2 &lit.hk2.Factory; implementation
            is responsible for implementing the <literal>provide()</literal> method that is used by HK2
            runtime to retrieve the injected instance. Those of you who worked with Guice binding API in the
            past will most likely find this concept very familiar.
        </para>

        <para>
            Once implemented, the factory can be used in a custom HK2 &lit.hk2.Binder; to define the
            new injection binding for &lit.jee6.servlet.HttpSession;. Finally, the implemented binder
            can be registered in your &jersey.server.ResourceConfig;:

            <programlisting language="java">import org.glassfish.hk2.utilities.binding.AbstractBinder;
...

public class MyApplication extends ResourceConfig {

    public MyApplication() {

        ...

        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(HttpSessionFactory.class).to(HttpSession.class)
                   .proxy(true).proxyForSameScope(false).in(RequestScoped.class);
            }
        });
    }
}</programlisting>

                Note that if we did not define any explicit injection scope for the new injection binding,
                By default, HK2 factories are bound in a HK2 &hk2.PerLookup; scope, which is in most
                cases a good choice, and it is suitable also in our example.
            </para>

            <para>
                To summarize the approach described above, here is a list of steps to follow
                when implementing custom injection provider in your Jersey application :

                <itemizedlist>
                    <listitem><simpara>Implement your own HK2 &lit.hk2.Factory; to provide the
                        injectable instances.</simpara></listitem>
                    <listitem><simpara>Use the HK2 &lit.hk2.Factory; to define an injection
                        binding for the injected instance via custom HK2 &lit.hk2.Binder;.</simpara></listitem>
                    <listitem><simpara>Register the custom HK2 &lit.hk2.Binder; in your application
                        &lit.jersey.server.ResourceConfig;.</simpara></listitem>
                </itemizedlist>
            </para>

            <para>
                While the &lit.hk2.Factory;-based approach is quite straight-forward and should help you to
                quickly prototype or even implement final solutions, you should bear in mind, that your
                implementation does not need to be based on factories. You can for instance bind your own
                types directly, while still taking advantage of HK2 provided dependency injection.
                Also, in your implementation you may want to pay more attention to defining or managing
                injection binding scopes for the sake of performance or correctness of your custom injection
                extension.

                <important>
                    <para>
                        While the individual injection binding implementations vary and depend on your use case,
                        to enable your custom injection extension in Jersey, you must register your custom HK2 &hk2.Binder;
                        implementation in your application &jersey.server.ResourceConfig;!
                    </para>
                </important>
            </para>
        </section>
        <section>
            <title>Injection Provider Using Jersey API</title>
            <para>
                To make the <literal>HttpSession</literal> injection work without using HK2 API,
                we will need to create a custom supplier that knows how to extract
                &lit.jee6.servlet.HttpSession; out of given &lit.jee6.servlet.HttpServletRequest;.

                <programlisting language="java">import java.util.function.Supplier
    ...

public class HttpSessionSupplier implements Supplier&lt;HttpSession&gt; {

    private final HttpServletRequest request;

    @Inject
    public HttpSessionSupplier(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public HttpSession get() {
        return request.getSession();
    }

}</programlisting>

                Once implemented, the supplier can be used in a custom Jersey &jersey.common.internal.inject.AbstractBinder;
                to define the new injection binding for &lit.jee6.servlet.HttpSession;. Finally, the implemented binder
                can be registered in your &jersey.server.ResourceConfig;:

                <programlisting language="java">import org.glassfish.jersey.internal.inject.AbstractBinder;
    ...
public class MyApplication extends ResourceConfig {

    public MyApplication() {

        ...

        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(HttpSessionSupplier.class).to(HttpSession.class)
                    .proxy(true).proxyForSameScope(false).in(RequestScoped.class);
            }
        });
    }
}</programlisting>
                   The default scope for Jersey binder is similarly as for the HK2, the
                &jersey.common.internal.inject.PerLookup;.
            </para>
            <para>
                To summarize the approach described above, here is a list of steps to follow
                when implementing custom injection provider in your Jersey application :

                <itemizedlist>
                    <listitem><simpara>Implement your own Supplier to provide the
                        injectable instances.</simpara></listitem>
                    <listitem><simpara>Use the Supplier to define an injection
                        binding for the injected instance via custom &jersey.common.internal.inject.AbstractBinder;.
                    </simpara></listitem>
                    <listitem><simpara>Register the custom &jersey.common.internal.inject.AbstractBinder; in your application
                        &lit.jersey.server.ResourceConfig;.</simpara></listitem>
                </itemizedlist>

                <important>
                    <para>
                        Similarly to the HK2, to enable your custom injection extension in Jersey,
                        you must register your custom &jersey.common.internal.inject.AbstractBinder;
                        implementation in your application &jersey.server.ResourceConfig;!
                    </para>
                </important>
            </para>
        </section>
    </section>

    <section>
        <title>Defining Custom Injection Annotation</title>

        <para>
            Java annotations are a convenient way for attaching metadata to various elements of Java code.
            Sometimes you may even decide to combine the metadata with additional functionality, such as
            ability to automatically inject the instances based on the annotation-provided metadata.
            The described scenario is one of the use cases where having means of defining a custom injection
            annotation in your Jersey application may prove to be useful. Obviously, this use case applies also
            to re-used existing, 3rd-party annotation types.
        </para>

        <para>
            In the following example, we will describe how a custom injection annotation can be supported.
            Let's start with defining a new custom <literal>SessionInject</literal> injection annotation
            that we will specifically use to inject instances of &jee6.servlet.HttpSession;
            (similarly to the previous example):

            <programlisting language="java">@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SessionInject { }</programlisting>

            The above <literal>@SessionInject</literal> annotation should be then used as follows:

            <programlisting language="java">@Path("di-resource")
public class MyDiResource {

    @SessionInject HttpSession httpSession;

    ...

}</programlisting>

            Again, the semantics remains the same as in the example described in the previous section.
            You want to have the actual HTTP Servlet session instance injected into your
            <literal>MyDiResource</literal> instance. This time however, you expect that the
            <literal>httpSession</literal> field to be injected must be annotated with
            a custom <literal>@SessionInject</literal> annotation. Obviously, in this simplistic case
            the use of a custom injection annotation is an overkill, however, the simplicity of the
            use case will help us to avoid use case specific distractions and allow us better focus on
            the important aspects of the job of defining a custom injection annotation.
        </para>
        <section>
            <title>Custom Injection Annotation using HK2</title>

        <para>
            If you remember from the previous section, to make the injection in the code snippet above work,
            you first need to implement the injection provider (HK2 &hk2.Factory;) as well as define the
            injection binding for the &lit.jee6.servlet.HttpSession; type. That part we have already
            done in the previous section.
            We will now focus on what needs to be done to inform the HK2 runtime about our <literal>@SessionInject</literal>
            annotation type that we want to support as a new injection point marker annotation. To do that,
            we need to implement our own HK2 &hk2.InjectionResolver; for the annotation as demonstrated
            in the following listing:

            <programlisting language="java">import javax.inject.Inject;
import javax.inject.Named;

import javax.servlet.http.HttpSession;

import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceHandle;

...

public class SessionInjectResolver implements InjectionResolver&lt;SessionInject&gt; {

    @Inject
    @Named(InjectionResolver.SYSTEM_RESOLVER_NAME)
    InjectionResolver&lt;Inject&gt; systemInjectionResolver;

    @Override
    public Object resolve(Injectee injectee, ServiceHandle&lt;?&gt; handle) {
        if (HttpSession.class == injectee.getRequiredType()) {
            return systemInjectionResolver.resolve(injectee, handle);
        }

        return null;
    }

    @Override
    public boolean isConstructorParameterIndicator() {
        return false;
    }

    @Override
    public boolean isMethodParameterIndicator() {
        return false;
    }
}</programlisting>

            The <literal>SessionInjectResolver</literal> above just delegates to the default
            HK2 system injection resolver to do the actual work.
        </para>

        <para>
            You again need to register your injection resolver with your Jersey application,
            and you can do it the same was as in the previous case. Following listing includes
            HK2 binder that registers both, the injection provider from the previous step
            as well as the new HK2 inject resolver with Jersey application &lit.jersey.server.ResourceConfig;.
            Note that in this case we're explicitly binding the <literal>SessionInjectResolver</literal>
            to a &jee6.inject.Singleton; scope to avoid the unnecessary proliferation of
            <literal>SessionInjectResolver</literal> instances in the application:

            <programlisting language="java">import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.binding.AbstractBinder;

import javax.inject.Singleton;

...

public class MyApplication extends ResourceConfig {

    public MyApplication() {

        ...

        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(HttpSessionFactory.class).to(HttpSession.class);

                bind(SessionInjectResolver.class)
                    .to(new TypeLiteral&lt;InjectionResolver&lt;SessionInject&gt;&gt;(){})
                    .in(Singleton.class);
            }
        });
    }
}</programlisting>
        </para>
        </section>
        <section>
            <title>Custom Injection Annotation using Jersey InjectionResolver</title>

            <para>
                Jersey also comes with its &jersey.common.internal.inject.InjectionResolver; used to translate into
                the HK2 &hk2.InjectionResolver; during runtime. The abstraction is important for allowing to support
                the custom injection annotation in various DI containers. For instance, the abstraction is used when
                supporting injection using &jaxrs.core.Context; in the CDI container (<literal>jersey-cdi2-se</literal> module).
            </para>
            <para>
                The SessionInjectResolver then looks as follows:
<programlisting language="java">import javax.inject.Inject;

import javax.servlet.http.HttpSession;

import org.glassfish.jersey.internal.inject.InjectionResolver;

...

public class SessionInjectResolver implements InjectionResolver&lt;SessionInject&gt; {

    private final InjectionManger injectionManager;

    public SessionInjectResolver(InjectionManager) {
        this.injectionManager = injectionManager;
    }

    @Override
    public Object resolve(Injectee injectee) {
        if (HttpSession.class == injectee.getRequiredType()) {
            return injectionManager.getInstance(HttpServletRequest.class).getSession();
        }
        return null;
    }

    @Override
    public boolean isConstructorParameterIndicator() {
        return false;
    }

    @Override
    public boolean isMethodParameterIndicator() {
        return false;
    }

    @Override
    public Class&lt;SessionInject&gt; getAnnotation() {
        return SessionInject.class;
    }
}</programlisting>

                The SessionInjectResolver uses &jersey.common.internal.inject.InjectionManager; described in
                <xref linkend="injection.manager"/>.
            </para>
            <para>
                Unlike with &hk2.link;, Jersey &jersey.common.internal.inject.InjectionResolver; can only be bound
                as instance in the &jersey.common.internal.inject.AbstractBinder;. That is why the
                &jersey.common.internal.inject.InjectionManager; is used in the <literal>InjectionResolver</literal>
                to resolve the <literal>HttpSession</literal> instance.
            </para>
            <para>
                The &jersey.common.internal.inject.InjectionResolver; can be registered in the with Jersey application
                &lit.jersey.server.ResourceConfig; as follows:

<programlisting language="java">import javax.ws.rs.core.Feature;

import org.glassfish.jersey.InjectionManagerProvider;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.InjectionManager;


import javax.inject.Singleton;

...

public class MyApplication extends ResourceConfig {

public MyApplication() {

    ...

    register(new Feature() {
        @Override
        public boolean configure(FeatureContext context) {
            final InjectionManager injectionManager = InjectionManagerProvider.getInjectionManager(context);
            context.register(new AbstractBinder() {
                @Override
                protected void configure() {
                    bind(new SessionInjectResolver(injectionManager)).to(HttpSession.class).in(Singleton.class);
                }
            });
            return true;
        }
    });
}</programlisting>
            </para>
        </section>
    </section>

    <section>
        <title>Custom Life Cycle Management</title>

        <para>
            The last use case discussed in this chapter will cover managing custom-scoped components
            within a Jersey application.
            If not configured otherwise, then all JAX-RS resources are by default managed on a per-request basis. A new instance
            of given resource class will be created for each incoming request that should be handled by that resource class.
            Let say you want to have your resource class managed in a per-session manner. It means a new instance of your
            resource class should be created only when a new Servlet &jee6.servlet.HttpSession; is established.
            (As with previous examples in the chapter, this example assumes the deployment of your application
            to a Servlet container.)
        </para>

        <para>
            Following is an example of such a resource class that builds on the support for
            &lit.jee6.servlet.HttpSession; injection from the earlier examples described in this chapter.
            The <literal>PerSessionResource</literal> class allows you to count the number of requests made within
            a single client session and provides you a handy sub-resource method to obtain the number via
            a HTTP &lit.http.GET; method call:

            <programlisting language="java">@Path("session")
public class PerSessionResource {

    @SessionInject HttpSession httpSession;

    AtomicInteger counter = new AtomicInteger();

    @GET
    @Path("id")
    public String getSession() {
        counter.incrementAndGet();
        return httpSession.getId();
    }

    @GET
    @Path("count")
    public int getSessionRequestCount() {
        return counter.incrementAndGet();
    }
}</programlisting>

            Should the above resource be per-request scoped (default option), you would never be able to obtain
            any other number but 1 from it's getReqs sub-resource method, because then for each request
            a new instance of our <literal>PerSessionResource</literal> class would get created with a fresh
            instance <literal>counter</literal> field set to 0.
            The value of this field would get incremented to 1 in the the <literal>getSessionRequestCount</literal>
            method before this value is returned.
            In order to achieve what we want, we have to find a way how to bind the instances of
            our <literal>PerSessionResource</literal> class to &lit.jee6.servlet.HttpSession; instances and
            then reuse those bound instances whenever new request bound to the same HTTP client session arrives.
            Let's see how to achieve this.
        </para>

        <para>
            To get better control over your Jersey component instantiation and life cycle,
            you need to implement a custom Jersey &jersey.server.spi.ComponentProvider; SPI,
            that would manage your custom components.
            Although it might seem quite complex to implement such a thing,
            the component provider concept in Jersey is in fact very simple. It allows you to define
            your own HK2 injection bindings for the types that you are interested in,
            while informing the Jersey runtime at the same time that it should back out and leave
            the component management to your provider in such a case.
            By default, if there is no custom component provider found for any given component type, Jersey
            runtime assumes the role of the default component provider and automatically defines the default
            HK2 binding for the component type.
        </para>

        <para>
            Following example shows a simple &lit.jersey.server.spi.ComponentProvider; implementation,
            for our use case. Some comments on the code follow.

            <programlisting language="java">import javax.inject.Inject;
import javax.inject.Provider;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
...
import org.glassfish.hk2.api.DynamicConfiguration;
import org.glassfish.hk2.api.DynamicConfigurationService;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.binding.BindingBuilderFactory;
import org.glassfish.jersey.server.spi.ComponentProvider;

@javax.ws.rs.ext.Provider
public class PerSessionComponentProvider implements ComponentProvider {

    private ServiceLocator locator;

    static class PerSessionFactory implements Factory&lt;PerSessionResource&gt;{
        static ConcurrentHashMap&lt;String, PerSessionResource&gt; perSessionMap
                = new ConcurrentHashMap&lt;String, PerSessionResource&gt;();


        private final Provider&lt;HttpServletRequest&gt; requestProvider;
        private final ServiceLocator locator;

        @Inject
        public PerSessionFactory(
                Provider&lt;HttpServletRequest&gt; request,
                ServiceLocator locator) {

            this.requestProvider = request;
            this.locator = locator;
        }

        @Override
        @PerLookup
        public PerSessionResource provide() {
            final HttpSession session = requestProvider.get().getSession();

            if (session.isNew()) {
                PerSessionResource newInstance = createNewPerSessionResource();
                perSessionMap.put(session.getId(), newInstance);

                return newInstance;
            } else {
                return perSessionMap.get(session.getId());
            }
        }

        @Override
        public void dispose(PerSessionResource r) {
        }

        private PerSessionResource createNewPerSessionResource() {
            final PerSessionResource perSessionResource = new PerSessionResource();
            locator.inject(perSessionResource);
            return perSessionResource;
        }
    }

    @Override
    public void initialize(ServiceLocator locator) {
        this.locator = locator;
    }

    @Override
    public boolean bind(Class&lt;?&gt; component, Set&lt;Class&lt;?&gt;&gt; providerContracts) {
        if (component == PerSessionResource.class) {

            final DynamicConfigurationService dynamicConfigService =
                locator.getService(DynamicConfigurationService.class);
            final DynamicConfiguration dynamicConfiguration =
                dynamicConfigService.createDynamicConfiguration();

            BindingBuilderFactory
                .addBinding(BindingBuilderFactory.newFactoryBinder(PerSessionFactory.class)
                .to(PerSessionResource.class), dynamicConfiguration);

            dynamicConfiguration.commit();

            return true;
        }
        return false;
    }

    @Override
    public void done() {
    }
}</programlisting>
        </para>

        <para>
            The first and very important aspect of writing your own &lit.jersey.server.spi.ComponentProvider;
            in Jersey is to store the actual HK2 &hk2.ServiceLocator; instance that will be passed to you as
            the only argument of the provider <literal>initialize</literal> method.
            Your component provider instance will not get injected at all so this is more or less your only chance
            to get access to the HK2 runtime of your application. Please bear in mind, that at the time when
            your component provider methods get invoked, the &lit.hk2.ServiceLocator; is not fully configured yet.
            This limitation applies to all component provider methods, as the main goal of any component provider
            is to take part in configuring the application's &lit.hk2.ServiceLocator;.
        </para>

        <para>
            Now let's examine the <literal>bind</literal> method, which is where your provider tells the HK2
            how to bind your component.
            Jersey will invoke this method multiple times, once for each type that is registered with the
            actual application.
            Every time the <literal>bind</literal> method is invoked, your component provider needs to decide
            if it is taking control over the component or not. In our case we know exactly which Java type
            we are interested in (<literal>PerSessionResource</literal> class),
            so the logic in our <literal>bind</literal> method is quite straightforward. If we see our
            <literal>PerSessionResource</literal> class it is our turn to provide our custom binding for the class,
            otherwise we just return false to make Jersey poll other providers and, if no provider kicks in,
            eventually provide the default HK2 binding for the component.
            Please, refer to the &hk2.link; documentation for the details of the concrete HK2 APIs used in
            the <literal>bind</literal> method implementation above. The main idea behind the code is that
            we register a new HK2 &hk2.Factory; (<literal>PerSessionFactory</literal>), to provide
            the <literal>PerSessionResource</literal> instances to HK2.
        </para>

        <para>
            The implementation of the <literal>PerSessionFactory</literal> is also included above.
            Please note that as opposed to a component provider implementation that should never itself rely
            on an injection support, the factory bound by our component provider would get injected just fine,
            since it is only instantiated later, once the Jersey runtime for the application is fully
            initialized including the fully configured HK2 runtime.
            Whenever a new session is seen, the factory instantiates and injects
            a new PerSessionResource instance. The instance is then stored in the perSessionMap for later use
            (for future calls).
        </para>

        <para>
            In a real life scenario, you would want to pay more attention to possible synchronization issues.
            Also, we do not consider a mechanism that would clean-up any obsolete resources for closed, expired or
            otherwise invalidated HTTP client sessions.
            We have omitted those considerations here for the sake of brevity of our example.
        </para>
    </section>
</chapter>
