ri-spi.xml 33.6 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"  [ ]>

<appendix id="ri-spi">
   <title>Integrating Weld into other environments</title>

   <para>
      If you want to use Weld in another environment, you will need to provide certain information to Weld via the
      integration SPI. In this Appendix we will briefly discuss the steps needed. 
   </para>
   
   <tip>
      <title>Enterprise Services</title>
      <para>
         If you just want to use managed beans, and not take advantage of enterprise services (EE resource injection,
         CDI injection into EE component classes, transactional events, support for CDI services in EJBs) and non-flat
         deployments, then the generic servlet support provided by the "Weld: Servlets" extension will be sufficient,
         and will work in any container supporting the Servlet API.
      </para>
   </tip>
    
   <para>
      All SPIs and APIs described have extensive JavaDoc, which spell out the detailed contract between the container
      and Weld.
   </para>
    
   <section>
      <title>The Weld SPI</title>
      
      <para>
         The Weld SPI is located in the <literal>weld-spi</literal> module, and packaged as
         <literal>weld-spi.jar</literal>. Some SPIs are optional, and should only be implemented if you need to override
         the default behavior; others are required.
      </para>
       
      <para>
         All interfaces in the SPI support the decorator pattern and provide a <literal>Forwarding</literal> class
         located in the <literal>helpers</literal> sub package. Additional, commonly used, utility classes, and standard
         implementations are also located in the <literal>helpers</literal> sub package.
      </para>
                
      <para>
         Weld supports multiple environments. An environment is defined by an implementation of the
         <literal>Environment</literal> interface. A number of standard environments are built in, and described by the
         <literal>Environments</literal> enumeration. Different environments require different services to be present
         (for example a Servlet container doesn't require transaction, EJB or JPA services). By default an EE
         environment is assumed, but you can adjust the environment by calling
         <literal>bootstrap.setEnvironment()</literal>.
      </para>
         
      <para>
         Weld uses a generic-typed service registry to allow services to be registered. All services implement the
         <literal>Service</literal> interface. The service registry allows services to be added and retrieved.
      </para>
      
      <section>
         <title>Deployment structure</title>
      
         <para>
            An application is often comprised of a number of modules. For example, a Java EE deployment may contain a
            number of EJB modules (containing business logic) and war modules (containing the user interface). A
            container may enforce certain <emphasis>accessibility</emphasis> rules which limit the visibility of classes
            between modules. CDI allows these same rules to apply to bean and observer method resolution. As the
            accessibility rules vary between containers, Weld requires the container to <emphasis>describe</emphasis>
            the deployment structure, via the <literal>Deployment</literal> SPI.
         </para>
         
         <para>
            The CDI specification discusses <emphasis>Bean Deployment Archives</emphasis> (BDAs)&#8212;archives which
            are marked as containing beans which should be deployed to the CDI container, and made available for
            injection and resolution. Weld reuses this description of <emphasis>Bean Deployment Archives</emphasis> in
            its deployment structure SPI. Each deployment exposes the BDAs which it contains; each BDA may also
            reference other which it can access. Together, the transitive closure of this graph forms the beans which
            are deployed in the application.
         </para>
         
         <para>
            To describe the deployment structure to Weld, the container should provide an implementation of
            <literal>Deployment</literal>.  <literal>Deployment.getBeanDeploymentArchives()</literal> allows Weld to
            discover the modules which make up the application. The CDI specification also allows beans to be specified
            programmatically as part of the bean deployment. These beans may, or may not, be in an existing BDA. For
            this reason, Weld will call <literal>Deployment.loadBeanDeploymentArchive(Class clazz)</literal> for each
            programmatically described bean.
         </para>
         
         <para>
            As programmatically described beans may result in additional BDAs being added to the graph, Weld will
            discover the BDA structure every time an unknown BDA is returned by
            <literal>Deployment.loadBeanDeploymentArchive</literal>.
         </para>
         
         <note>
            <title>Virtual BDAs</title>
            <para>
               In a strict container, each BDA might have to explicitly specify which other BDAs it can access. However
               many containers will allow an easy mechanism to make BDAs bi-directionally accessible (such as a library
               directory). In this case, it is allowable (and reasonable) to describe all such archives as a single,
               'virtual' <literal>BeanDeploymentArchive</literal>.  
            </para>
            
            <para>
               A container, might, for example, use a flat accessibility structure for the application. In this case, a
               single <literal>BeanDeploymentArchive</literal> would be attached to the <literal>Deployment</literal>.
            </para>
         </note>

         <para>
            <literal>BeanDeploymentArchive</literal> provides three methods which allow it's contents to be discovered
            by Weld&#8212;<literal>BeanDeploymentArchive.getBeanClasses()</literal> must return all the classes in the
            BDA, <literal>BeanDeploymentArchive.getBeansXml()</literal> must return all the deployment descriptors in
            the archive, and <literal>BeanDeploymentArchive.getEjbs()</literal> must provide an EJB descriptor for every
            EJB in the BDA, or an empty list if it is not an EJB archive. 
         </para>
         
         <para>
            BDA X may also reference another BDA Y whose beans can be resolved by, and injected into, any bean in BDA X.
            These are the accessible BDAs, and every BDA that is directly accessible by BDA X should be returned.  A BDA
            will also have BDAs which are accessible transitively, and the transitive closure of the sub-graph of BDA X
            describes all the beans resolvable by BDA X.
         </para>
         
         <tip>
            <title>Matching the classloader structure for the deployment</title>
            
            <para>
               In practice, you can regard the deployment structure represented by <literal>Deployment</literal>, and
               the virtual BDA graph as a mirror of the classloader structure for a deployment. If a class can from BDA
               X can be loaded by another in BDA Y, it is accessible, and therefore BDA Y's accessible BDAs should
               include BDA X. 
            </para>
         </tip>
         
         <para>
            To specify the directly accessible BDAs, the container should provide an implementation of
            <literal>BeanDeploymentArchive.getBeanDeploymentArchives()</literal>.
         </para>
         
         <tip>
            <para>
               Weld allows the container to describe a circular graph, and will convert a graph to a tree as part of the
               deployment process.
            </para>
         </tip>
         
         <para>
            Certain services are provided for the whole deployment, whilst some are provided per-BDA. BDA services are
            provided using <literal>BeanDeploymentArchive.getServices()</literal> and only apply to the BDA on which
            they are provided.
         </para>
         
      </section>
       
      <section>
         <title>EJB descriptors</title>
         
         <para>
            Weld delegates EJB 3 bean discovery to the container so that it doesn't duplicate the work done by the EJB
            container, and respects any vendor-extensions to the EJB definition.
         </para>
               
         <para>
            The <literal>EjbDescriptor</literal> should return the relevant metadata as defined in the EJB
            specification. Each business interface of a session bean should be described using a
            <literal>BusinessInterfaceDescriptor</literal>.
         </para>
         
       </section>
       
       <section>
         <title>EE resource injection and resolution services</title>
         
         <para>
            All the EE resource services are per-BDA services, and may be provided using one of two methods. Which
            method to use is at the discretion of the integrator.
         </para>
         
         <para>
            The integrator may choose to provide all EE resource injection services themselves, using another library or
            framework. In this case the integrator should use the <literal>EE</literal> environment, and implement the
            <xref linkend="injection.services" /> SPI.
         </para>
         
         <para>
            Alternatively, the integrator may choose to use CDI to provide EE resource injection. In this case, the
            <literal>EE_INJECT</literal> environment should be used, and the integrator should implement the <xref
            linkend="ejb.services.resolution"/>, <xref linkend="resource.services"/> and <xref linkend="jpa.services"/>.
         </para>
         
         <important>
            <para>
               CDI only provides annotation-based EE resource injection; if you wish to provide deployment descriptor
               (e.g. <literal>ejb-jar.xml</literal>) injection, you must use <xref linkend="injection.services"/>.
            </para>
         </important>
         
         <para>
            If the container performs EE resource injection, the injected resources must be serializable. If EE resource
            injection is provided by Weld, the resolved resource must be serializable.
         </para>
          
         <tip>
            <para>
               If you use a non-EE environment then you may implement any of the EE service SPIs, and Weld will provide
               the associated functionality. There is no need to implement those services you don't need!
            </para>
         </tip>
         
      </section>
         
      <section id="ejb.services">
         <title>EJB services</title>
         
         <para>
            EJB services are split between two interfaces which are both per-BDA.
         </para>
         
         <para>
            <literal>EJBServices</literal> is used to resolve local EJBs used to back session beans, and must always be
            provided in an EE environment.  <literal>EJBServices.resolveEjb(EjbDescriptor ejbDescriptor)</literal>
            returns a wrapper&#8212;<literal>SessionObjectReference</literal>&#8212;around the EJB reference. This
            wrapper allows Weld to request a reference that implements the given business interface, and, in the case of
            SFSBs, both request the removal of the EJB from the container and query whether the EJB has been previously
            removed.
         </para>
         
         <para id="ejb.services.resolution">
            <literal>EJBResolutionServices.resolveEjb(InjectionPoint ij)</literal> allows the resolution of
            <literal>@EJB</literal> (for injection into managed beans). This service is not required if the
            implementation of <xref linkend="injection.services"/> takes care of <literal>@EJB</literal> injection.
         </para>
         
      </section>
       
      <section id="jpa.services">
         <title>JPA services</title>
         
         <para>
            Just as EJB resolution is delegated to the container, resolution of <literal>@PersistenceContext</literal>
            for injection into managed beans (with the <literal>InjectionPoint</literal> provided), is delegated to the
            container.
         </para>
         
         <para>
            To allow JPA integration, the <literal>JpaServices</literal> interface should be implemented. This service
            is not required if the implementation of <xref linkend="injection.services"/> takes care of
            <literal>@PersistenceContext</literal> injection.
         </para>
         
      </section>
       
      <section>
         <title>Transaction Services</title>
         
         <para>
            Weld delegates JTA activities to the container. The SPI provides a couple hooks to easily achieve this with
            the <literal>TransactionServices</literal> interface.
         </para>
      
         <para>
            Any <literal>javax.transaction.Synchronization</literal> implementation may be passed to the
            <literal>registerSynchronization()</literal> method and the SPI implementation should immediately register
            the synchronization with the JTA transaction manager used for the EJBs.
         </para>
      
         <para>
            To make it easier to determine whether or not a transaction is currently active for the requesting thread,
            the <literal>isTransactionActive()</literal> method can be used. The SPI implementation should query the
            same JTA transaction manager used for the EJBs.
         </para>
      </section>
      
      <section id="resource.services">
         <title>Resource Services</title>
           
         <para>
            The resolution of <literal>@Resource</literal> (for injection into managed beans) is delegated to the
            container. You must provide an implementation of <literal>ResourceServices</literal> which provides these
            operations.  This service is not required if the implementation of <xref linkend="injection.services"/>
            takes care of <literal>@Resource</literal> injection.
         </para>
      </section>
      
      <section id="injection.services">
         <title>Injection Services</title>
         
         <para>
            An integrator may wish to use <literal>InjectionServices</literal> to provide additional field or method
            injection over-and-above that provided by Weld. An integration into a Java EE environment may use
            <literal>InjectionServices</literal> to provide EE resource injection for managed beans.
         </para>
         
         <para>
            <literal>InjectionServices</literal> provides a very simple contract, the
            <literal>InjectionServices.aroundInject(InjectionContext ic);</literal> intercepter will be called for every
            instance that CDI injects, whether it is a contextual instance, or a non-contextual instance injected by
            <literal>InjectionTarget.inject()</literal>.
         </para>
         
         <para>
            The <literal>InjectionContext</literal> can be used to discover additional information about the injection
            being performed, including the <literal>target</literal> being injected.  <literal>ic.proceed()</literal>
            should be called to perform CDI-style injection, and call initializer methods.
         </para>
         
      </section>
      
      <section>
         <title>Security Services</title>
         
         <para>
            In order to obtain the <literal>Principal</literal> representing the current caller identity, the container
            should provide an implementation of <literal>SecurityServices</literal>.
         </para>

      </section>
      
      <section>
         <title>Bean Validation Services</title>
         
         <para>
            In order to obtain the default <literal>ValidatorFactory</literal> for the application deployment, the
            container should provide an implementation of <literal>ValidationServices</literal>.
         </para>

      </section>
      
      <section>
         <title>Identifying the BDA being addressed</title>
         
         <para>
            When a client makes a request to an application which uses Weld, the request may be addressed at any of the
            BDAs in the application deployment. To allow Weld to correctly service the request, it needs to know which
            BDA the request is addressed at.  Where possible, Weld will provide some context, but use of these by the
            integrator is optional.
         </para>
         
         <tip>
            <para>
               Most Servlet contains use a classloader-per-war, this may provide
               a good way to identify the BDA in use for web requests.
            </para>
         </tip>
         
         <para>
            When Weld needs to identify the BDA, it will use one of these services, depending on what is servicing the
            request:
         </para>
         
         <variablelist>
            <varlistentry>
               <term><literal>ServletServices.getBeanDeploymentArchive(ServletContext ctx)</literal></term>
               <listitem>
                  <para>
                     Identify the war in use. The <literal>ServletContext</literal> is provided for additional context.
                  </para>
               </listitem>
            </varlistentry>
         </variablelist>
         
      </section>
      
      <section>
         <title>The bean store</title>
         
         <para>
            Weld uses a map like structure to store bean instances -
            <literal>org.jboss.weld.context.api.BeanStore</literal>. You may find
            <literal>org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore</literal> useful.
         </para>
      </section>
    
      <section>
         <title>The application context</title>
         
         <para>
            Weld expects the Application Server or other container to provide the storage for each application's
            context. The <literal>org.jboss.weld.context.api.BeanStore</literal> should be implemented to provide an
            application scoped storage.
         </para>
         
      </section>
       
      <section>
         <title>Initialization and shutdown</title>
         <para>
            The <literal>org.jboss.weld.bootstrap.api.Bootstrap</literal> interface defines the initialization for Weld,
            bean deployment and bean validation. To boot Weld, you must create an instance of
            <literal>org.jboss.weld.bootstrap.WeldBeansBootstrap</literal> (which implements
            <literal>Boostrap</literal>), tell it about the services in use, and then request the container start.
         </para>
         
         <para>
            The bootstrap is split into phases, container initialization, bean deployment, bean validation and shutdown.
            Initialization will create a manager, and add the built-in contexts, and examine the deployment structure.
            Bean deployment will deploy any beans (defined using annotations, programtically, or built in). Bean
            validation will validate all beans.
         </para>
         
         <para>
            To initialize the container, you call <literal>Bootstrap.startInitialization()</literal>. Before calling
            <literal>startInitialization()</literal>, you must register any services required by the environment. You
            can do this by calling, for example, <literal>bootstrap.getServices().add(JpaServices.class, new
            MyJpaServices())</literal>.  You must also provide the application context bean store.
         </para>
         
         <para>
            Having called <literal>startInitialization()</literal>, the <literal>Manager</literal> for each BDA can be
            obtained by calling <literal>Bootstrap.getManager(BeanDeploymentArchive bda)</literal>.
         </para>
         
         <para>
            To deploy the discovered beans, call <literal>Bootstrap.deployBeans()</literal>.
         </para>
         
         <para>
            To validate the deployed beans, call <literal>Bootstrap.validateBeans()</literal>.
         </para>
         
         <para>
            To place the container into a state where it can service requests, call
            <literal>Bootstrap.endInitialization()</literal>
         </para>
         
         <para>
            To shutdown the container you call <literal>Bootstrap.shutdown()</literal>. This allows the container to
            perform any cleanup operations needed.
         </para>
         
       </section>
       
       <section>
         <title>Resource loading</title>
         
         <para>
            Weld needs to load classes and resources from the classpath at various times. By default, they are loaded
            from the Thread Context ClassLoader if available, if not the same classloader that was used to load Weld,
            however this may not be correct for some environments. If this is case, you can implement
            <literal>org.jboss.weld.spi.ResourceLoader</literal>.
         </para>

       </section>
   
    </section>
    
    <section>
      <title>The contract with the container</title>
      
      <para>
         There are a number of requirements that Weld places on the container for correct functioning that fall outside
         implementation of APIs.
      </para>
      
      <variablelist>
         <varlistentry>
            <term>
               Classloader isolation
            </term>
            <listitem>
               <para>
                  If you are integrating Weld into an environment that supports deployment of multiple applications, you
                  must enable, automatically, or through user configuation, classloader isolation for each CDI
                  application.
               </para>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               Servlet
            </term>
            <listitem>
               <para>
                  If you are integrating Weld into a Servlet environment you must register
                  <literal>org.jboss.weld.servlet.WeldListener</literal> as a Servlet listener, either
                  automatically, or through user configuration, for each CDI application which uses Servlet.
               </para>
               <para>
                  You must ensure that that <literal>WeldListener.contextInitialized()</literal> is called
                  after beans are deployed is complete (<literal>Bootstrap.deployBeans()</literal> has been called). 
               </para>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               JSF
            </term>
            <listitem>
            
               <para>
                  If you are integrating Weld into a JSF environment you must register
                  <literal>org.jboss.weld.jsf.WeldPhaseListener</literal> as a phase listener.
               </para>
               
               <para>
                  If you are integrating Weld into a JSF environment you must register
                  <literal>org.jboss.weld.el.WeldELContextListener</literal> as an EL Context listener.
               </para>
               
               <para>
                  If you are integrating Weld into a JSF environment you must register
                  <literal>org.jboss.weld.jsf.ConversationAwareViewHandler</literal> as a delegating view handler.
               </para>
               
               <para>
                  If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and
                  then call <literal>BeanManager.wrapExpressionFactory()</literal>, passing
                  <literal>Application.getExpressionFactory()</literal> as the argument. The wrapped expression factory
                  must be used in all EL expression evaluations performed by JSF in this web application. 
               </para>
                       
               <para>
                  If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and
                  then call <literal>BeanManager.getELResolver()</literal>, The returned EL resolver should be
                  registered with JSF for this web application. 
               </para>
               
               <tip>
                  <para>
                     There are a number of ways you can obtain the bean manager for the module. You could call
                     <literal>Bootstrap.getManager()</literal>, passing in the BDA for this module. Alternatively, you
                     could use the injection into Java EE component classes, or look up the bean manager in JNDI. 
                  </para>
               </tip>
               
               <para>
                  If you are integrating Weld into a JSF environment you must register
                  <literal>org.jboss.weld.servlet.ConversationPropagationFilter</literal> as a Servlet listener,
                  either automatically, or through user configuration, for each CDI application which uses JSF.
                  This filter can be registered for all Servlet deployment safely.
               </para>
               
               <note>
                  <para>
                     Weld only supports JSF 1.2 and above.
                  </para>
               </note>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               JSP
            </term>
            <listitem>
               
               <para>
                  If you are integrating Weld into a JSP environment you must register
                  <literal>org.jboss.weld.el.WeldELContextListener</literal> as an EL Context listener.
               </para>
               
               <para>
                  If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and
                  then call <literal>BeanManager.wrapExpressionFactory()</literal>, passing
                  <literal>Application.getExpressionFactory()</literal> as the argument. The wrapped expression factory
                  must be used in all EL expression evaluations performed by JSP. 
               </para>
               
               <para>
                  If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and
                  then call <literal>BeanManager.getELResolver()</literal>, The returned EL resolver should be
                  registered with JSP for this web application. 
               </para>
               
               <tip>
                  <para>
                     There are a number of ways you can obtain the bean manager for the module. You could call
                     <literal>Bootstrap.getManager()</literal>, passing in the BDA for this module. Alternatively, you
                     could use the injection into Java EE component classes, or look up the bean manager in JNDI. 
                  </para>
               </tip>
               
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               Session Bean Interceptor
            </term>
            <listitem>
               <para>
                  If you are integrating Weld into an EJB environment you must register the <literal>aroundInvoke</literal> method of
                  <literal>org.jboss.weld.ejb.SessionBeanInterceptor</literal> as a EJB around-invoke interceptor for all EJBs in the
                  application, either automatically, or through user configuration, for each CDI application which
                  uses enterprise beans. If you are running in a EJB 3.1 environment, you should register this as an around-timeout
                  interceptor as well.
               </para>
               <important>
                  <para>
                     You must register the <literal>SessionBeanInterceptor</literal> as the inner most interceptor in
                     the stack for all EJBs. 
                  </para>
               </important>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               The <literal>weld-core.jar</literal>
            </term>
            <listitem>
               <para>
                  Weld can reside on an isolated classloader, or on a shared classloader. If you choose to use an
                  isolated classloader, the default <literal>SingletonProvider</literal>,
                  <literal>IsolatedStaticSingletonProvider</literal>, can be used. If you choose to use a shared
                  classloader, then you will need to choose another strategy. 
               </para>   
               <para>
                  You can provide your own implementation of <literal>Singleton</literal> and
                  <literal>SingletonProvider</literal> and register it for use using
                  <literal>SingletonProvider.initialize(SingletonProvider provider)</literal>.
               </para>
               <para>
                  Weld also provides an implementation of Thread Context Classloader per application strategy, via the
                  <literal>TCCLSingletonProvider</literal>.
               </para>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               Binding the manager in JNDI
            </term>
            <listitem>
               <para>
                  You should bind the bean manager for the bean deployment archive into JNDI at
                  <literal>java:comp/Manager</literal>. The type should be
                  <literal>javax.enterprise.inject.spi.BeanManager</literal>. To obtain the correct bean manager for the
                  bean deployment archive, you may call
                  <literal>bootstrap.getBeanManager(beanDeploymentArchive)</literal>  
               </para>
            </listitem>
         </varlistentry>
         <varlistentry>
            <term>
               Performing CDI injection on Java EE component classes
            </term>
            <listitem>
               <para>
                  The CDI specification requires the container to provide injection into non-contextual resources for
                  all Java EE component classes. Weld delegates this responsibility to the container. This can be
                  achieved using the CDI defined <literal>InjectionTarget</literal> SPI. Furthermore, you must perform
                  this operation on the correct bean manager for the bean deployment archive containing the EE component
                  class.
               </para>
               
               <para>
                  The CDI specification also requires that a <literal>ProcessInjectionTarget</literal> event is fired
                  for every Java EE component class. Furthermore, if an observer calls
                  <literal>ProcessInjectionTarget.setInjectionTarget()</literal> the container must use <emphasis>the
                  specified</emphasis> injection target to perform injection.
               </para>
               
               <para>
                  To help the integrator, Weld provides <literal>WeldManager.fireProcessInjectionTarget()</literal>
                  which returns the <literal>InjectionTarget</literal> to use.
               </para>
               
               <programlisting><![CDATA[// Fire ProcessInjectionTarget, returning the InjectionTarget
// to use
InjectionTarget it = weldBeanManager.fireProcessInjectionTarget(clazz);

// Per instance required, create the creational context
CreationalContext<?> cc = beanManager.createCreationalContext(null);

// Produce the instance, performing any constructor injection required
Object instance = it.produce();

// Perform injection and call initializers
it.inject(instance, cc);

// Call the post-construct callback
it.postConstruct(instance);

// Call the pre-destroy callback
it.preDestroy(instance);

// Clean up the instance
it.dispose();
cc.release();]]></programlisting>
               <para>
                  The container may intersperse other operations between these calls. Further, the integrator may choose
                  to implement any of these calls in another manner, assuming the contract is fulfilled.
               </para>
               <para>
                  When performing injections on EJBs you must use the Weld-defined SPI,
                  <literal>WeldManager</literal>. Furthermore, you must perform this operation on the correct bean
                  manager for the bean deployment archive containing the EJB.
               </para>
               <programlisting><![CDATA[// Obtain the EjbDescriptor for the EJB
// You may choose to use this utility method to get the descriptor
EjbDescriptor<?> ejbDescriptor = beanManager.getEjbDescriptor(ejbName);

// Get an the Bean object
Bean<?> bean = beanManager.getBean(ejbDescriptor);

// Create the injection target
InjectionTarget it = deploymentBeanManager.createInjectionTarget(ejbDescriptor);

// Per instance required, create the creational context
CreationalContext<?> cc = deploymentBeanManager.createCreationalContext(bean);

// Perform injection and call initializers
it.inject(instance, cc);

// You may choose to have CDI call the post construct and pre destroy
// lifecycle callbacks

// Call the post-construct callback
it.postConstruct(instance);

// Call the pre-destroy callback
it.preDestroy(instance);

// Clean up the instance
it.dispose();
cc.release();]]></programlisting>
            </listitem>
         </varlistentry>
      </variablelist>
    </section>

<!--
vim:et:ts=3:sw=3:tw=120
-->
</appendix>