Choose EJB to be injected without recompiling

后端 未结 3 825
离开以前
离开以前 2020-12-21 01:11

Imagine you have two implementations of a @Local interface

@Local
public interface LocalInterface {
}

@Stateless
public class MyFirstImplementa         


        
相关标签:
3条回答
  • 2020-12-21 01:50

    You can achieve it using the deployment descriptor - ejb-jar.xml. Something like this (might not be 100% accurate, but I think you've got the point):

    <ejb-jar> 
       <enterprise-beans>
          <session>
             <ejb-name>MyClass</ejb-name>
             <ejb-ref>
                <ejb-ref-name>ejb/myLocalReferencedBean</ejb-ref-name>
                <ejb-ref-type>Session</ejb-ref-type>
                <local>com.yourpackage.LocalInterface</local>
                <ejb-link>MyFirstImplementation</ejb-link>
                <injection-target>local</injection-target>
             </ejb-ref>
          </session>
    
          <session>
             <ejb-name>MyFirstImplementation</ejb-name>
             <!-- ... -->
          </session>
          <session>
             <ejb-name>MySecondImplementation</ejb-name>
             <!-- ... -->
          </session>
       </enterprise-beans>
    </ejb-jar>
    

    Another way is to use the CDI as described here: Inject @EJB bean based on conditions

    0 讨论(0)
  • 2020-12-21 02:03

    The method outlined by PedroKowalski is a typical way to do this. Another trick with respect to the "external configuration property", is simply configuring your builder such that only 1 implementation ends up in the jar you generate that holds the EJBs.

    So you don't have to recompile classes or change any source code, but you do have to rebuild your jar to choose another implementation.

    0 讨论(0)
  • 2020-12-21 02:04

    Another approach is to find the EJB reference with JNDI instead of relying on the automatic injection, just in case it could help anyone else:

    public class MyClass {
       LocalInterface local;
    
       @PostConstruct
       public void init() {
           local = findImplementation();
       }
    
       private LocalInterface findImplementation() {
           try {
                InitialContext context = new InitialContext();
                String ejbPath = // read from an external property
                return (LocalInterface) context.lookup(ejbPath);
           } catch ... { ... }
       }
    }
    

    This is what I finally did, because with JBoss 5 (< Java EE 6, EJB 3.0) you can not make use of the useful @Produces annotation. I mark PedroKowalski's answer as accepted because CDI annotations seem to be the better solution if you do not have other restrictions.

    0 讨论(0)
提交回复
热议问题