Derleme yapılmadan enjekte edilecek EJB'yi seçin

@Local arabiriminin iki uygulamasının olduğunu düşünün.

@Local
public interface LocalInterface {
}

@Stateless
public class MyFirstImplementation implements LocalInterface {
}

@Stateless
public class MySecondImplementation implements LocalInterface {
}

Ve ben, kullanmak istediğim (MyFirstImplementation veya MySecondImplementation) projeyi (yani, çalışma zamanında veya harici bir yapılandırma özelliği kullanarak) yeniden derlemeden seçmek istiyorum.

public class MyClass {
   @EJB
   LocalInterface local;
}

Bir uygulama seçildiğinde, değişmek zorunda değildir. Eğer yardımcı olursa JBoss 5.1 kullanıyorum.

3

3 cevap

Başka bir yaklaşım, JNDI ile otomatik enjeksiyona dayanmak yerine EJB referansını bulmaktır.

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 set PedroKowalski's answer as accepted as CDI annotations seems to be the better solution if you do not have other restrictions.

2
katma
Ne yazık ki Sınıfım 'un bulunduğu kodunun web.xml ' inin bildirimi sağlayabilmesi gerekir. JNDI ağacındaki fasulyeye bak. alt öğesi, java: comp/env altında EJB'yi nerede bulacağınızı gösterir. web.xml 'i değiştirmek, açıkça bir yapım zamanı değişikliğidir.
katma yazar lotz, kaynak

Dağıtım açıklamasını kullanarak elde edebilirsiniz - ejb-jar.xml . Bunun gibi bir şey (% 100 doğru olmayabilir, ama sanırım şu noktaya varmışsınız):

 
   
      
         MyClass
         
            ejb/myLocalReferencedBean
            Session
            com.yourpackage.LocalInterface
            MyFirstImplementation
            local
         
      

      
         MyFirstImplementation
         <!-- ... -->
      
      
         MySecondImplementation
         <!-- ... -->
      
   

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

2
katma
Teşekkür ederim. "MyClass" bir EJB'nin kendisi değilse ejb-jar çözümü işe yaramaz çünkü DTD'ye göre, ev/uzak arabirimleri belirtmeniz gerekir. CDI yaklaşımı sadece yanılmıyorsam JEE 6 için geçerlidir.
katma yazar Guido García, kaynak
@ GuidoGarcía haklısın - MyClass bir EJB sınıfı olmalı. CDI çözümü daha esnek bir yapıya sahiptir, çünkü konfigürasyonu başka bir yere bile yerleştirebilirsiniz - yani veritabanı. Ayrıca, @Inject 'i kullandığınız her yerde çalışır. Sadece küçük bir açıklama: bir xml şeması ve bir DTD değil. Ev/uzak arabirimler gerekli değildir - kullandığınız EJB sürümüne bağlıdır.
katma yazar Piotr Nowicki, kaynak

PedroKowalski tarafından özetlenen yöntem, bunu yapmak için tipik bir yoldur. "Harici konfigürasyon özelliği" ile ilgili başka bir numara, oluşturucunuzu EJB'leri barındıran üründe yalnızca 1 uygulamanın bittiği şekilde yapılandırmanızı basitçe basitleştirir.

Yani, sınıfları yeniden derlemek veya herhangi bir kaynak kodunu değiştirmek zorunda değilsiniz, ancak başka bir uygulama seçmek için kavanozunuzu yeniden oluşturmanız gerekir.

1
katma
Teşekkürler Arjan. Mevcut yaklaşımın kullanımı budur, ancak artık geçerli değildir çünkü kavanozun yeniden oluşturulması bir üretim ortamında bir seçenek değildir.
katma yazar Guido García, kaynak