<?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 &jee9.jakarta.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 &jee9.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.jee9.servlet.HttpSession;-scoped JAX-RS resources.
      </para>

        <para>
            Jersey implementation allows you to directly inject &jee9.servlet.HttpServletRequest; instance into
            your JAX-RS components.
            It is quite straight forward to get the appropriate &lit.jee9.servlet.HttpSession; instance out of the
            injected request instance.
            Let say, you want to get &lit.jee9.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.jee9.servlet.HttpSession; out of given &lit.jee9.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.jee9.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.jee9.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.jee9.servlet.HttpSession; out of given &lit.jee9.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.jee9.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 &jee9.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.jee9.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 jakarta.inject.Inject;
import jakarta.inject.Named;

import jakarta.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 &jee9.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 jakarta.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 jakarta.inject.Inject;

import jakarta.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 jakarta.ws.rs.core.Feature;

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


import jakarta.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 &jee9.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.jee9.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.jee9.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 jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.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;

@jakarta.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>
