选择要注入的EJB而不重新编译

时间:2011-10-28 09:51:17

标签: java-ee dependency-injection ejb

想象一下,您有两个@Local接口

的实现
@Local
public interface LocalInterface {
}

@Stateless
public class MyFirstImplementation implements LocalInterface {
}

@Stateless
public class MySecondImplementation implements LocalInterface {
}

我想选择而不重新编译项目(即在运行时或使用外部配置属性)我想使用哪个(MyFirstImplementation或MySecondImplementation)。

public class MyClass {
   @EJB
   LocalInterface local;
}

一旦选择了一个实现,就不必更改。如果有帮助,我正在使用JBoss 5.1。

3 个答案:

答案 0 :(得分:2)

您可以使用部署描述符ejb-jar.xml来实现它。这样的事情(可能不是100%准确,但我认为你已经明白了):

<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>

另一种方法是使用此处所述的CDI:Inject @EJB bean based on conditions

答案 1 :(得分:2)

另一种方法是使用JNDI查找EJB引用,而不是依赖于自动注入,以防它可以帮助其他任何人:

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 ... { ... }
   }
}

这是我最终做的,因为使用JBoss 5(&lt; Java EE 6,EJB 3.0),您无法使用有用的@Produces注释。如果您没有其他限制,我将PedroKowalski's answer设置为CDI注释似乎是更好的解决方案。

答案 2 :(得分:1)

PedroKowalski概述的方法是一种典型的方法。关于“外部配置属性”的另一个技巧是简单地配置构建器,使得只有1个实现在您生成的容纳EJB的jar中结束。

因此您不必重新编译类或更改任何源代码,但您必须重建jar以选择其他实现。