2010-01-29 14 views
29

nolu Spring bean'ı ayarlama JMS bağlantı fabrikasını Java uygulamamın içine enjekte etmek için Spring kullanıyorum. Bu fabrika sadece üretim ortamında gerekli olduğu için, ben geliştirirken değil, ben fasulye tanımı benim ana applicationContext.xml içine dahil ayrı bir XML koydu. Üretim ortamlarında bu ekstra dosya normal fasulye tanımını içerir. Yerel dev ortamımda bu fasulyenin boş olmasını isterim. Bean tanımını tamamen kaldırmaya çalışmak, Spring'in bilmediği bir referans kimliğine rastladığında açık bir şekilde bir hataya neden oldu.Kasıtlı olarak

Bu nedenle, yalnızca boş döndürecek bir fabrika çekirdeği oluşturmayı denedim. Bunu yaparsam, Spring (2.5.x), FactoryBean arabiriminin Spring API'sı belgesine dayanarak fabrikanın null değerini döndürdüğünü iddia ediyordu. Bunu çalışmak için bekledim (bkz. Spring API doc).

<bean id="jmsConnectionFactoryFactory" class="de.airlinesim.jms.NullJmsConnectionFactoryFactory" /> 

<bean id="jmsConnectionFactory" factory-bean="jmsConnectionFactoryFactory" factory-method="getObject"/> 

Ne Bunu yapmanın "doğru" yolu olacaktır:

XML şuna benzer?

cevap

20

factory-bean/factory-methodnull ile çalışmaz, ancak özel FactoryBean uygulama çalışıyor:

public class NullFactoryBean implements FactoryBean<Void> { 

    public Void getObject() throws Exception { 
     return null; 
    } 

    public Class<? extends Void> getObjectType() { 
     return null; 
    } 

    public boolean isSingleton() { 
     return true; 
    } 
} 
<bean id="jmsConnectionFactory" class = "com.sample.NullFactoryBean" /> 
+6

Bunun için bir açık özellik isteği var, ama 2 yıldır orada oturuyor ... oy verebileceği için yardım edebilir: http://jira.springframework.org/browse/SPR-5320 – skaffman

+0

Eğer bu benim için işe yaramadı Çekirdeği bir '@ Autowired' bağlamında kullandı. –

+0

Eğer null döndürürseniz BeanCreationException alıyorum. Neden: org.springframework.beans.factory.BeanCreationException: Sınıf yolu kaynağında [nex.xml] tanımlı 'nullObject' adı verilen fasulye yaratılırken hata oluştu: fabrikada 'NullFactoryBean' null döndürüldü – endless

-1

Özel <null> fasulye öğesinden yararlanabilir misiniz? Örneğin. the doc den

<bean class="ExampleBean"> 
<property name="email"><null/></property> 
</bean> 

, bölüm 3.3.2.5

+1

. Ama bu noktada, sadece gerçek bir fasülye veya null'a (eğer bu mümkün ise) başvurması gereken "jmsConnectionFactory" referans kimliğini sağladım. – Lunikon

27

Ben güzelim Spring'in null'u bir fasulye kimliği veya takma adıyla ilişkilendirmenize izin vermeyeceğinden emin olun. Özellikleri null olarak ayarlayarak bunu halledebilirsiniz. Eğer Bahar 3.0'da

<bean class="ExampleBean"> 
    <property name="email"><null/></property> 
</bean> 

Bahar 2,5 bu nasıl yaptığını İşte

var, ayrıca Spring expression language (SpEL) kullanmak gerekir; Örneğin.

<bean class="ExampleBean"> 
    <property name="email" value="#{ null }"/> 
</bean> 

veya null olarak değerlendirilen herhangi bir Spel ifade

.

Ve eğer bir yer tutucu yapılandırıcımızı kullanıyorsanız, hatta bu yapabilirdi:

some.prop=null 

veya

some.prop=some.bean.id 
: some.prop gibi bir özellik dosyasında tanımlanabilir

<bean class="ExampleBean"> 
    <property name="email" value="#{ ${some.prop} }`"/> 
</bean> 

Not: Spel (henüz) kullanmamıştım, bu yüzden som ile ilgili sorunlar olabilir Yukarıdaki e işareti ...

+1

Bu çözümü çok tercih ediyorum; özel bir fabrika fasulyesinin yaratılmasını gerektirmez – Richard

4

Yukarıda belirtilenlerden bazıları, axtact'ın cevabı Otomatik Kablolama bağlamlarında çalışmaz, burada Spring getObjectType() yönteminden doğru bilgileri kullanır.

 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [xxxxxxxxxxxxx] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=yyyyyyyyyyyyyyyy)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotatio 

Yani burada kullanıcıların inşaatında objectype zorlamak için izin vermeye, küçük varyasyon var: Yani böyle hatalar ile bitirmek olabilir. Bir yapıcı-arg yerine bir özellik kullanmak işe yaramadı çünkü Spring bu bağlamda fasulyeleri tam olarak başlatmıyor. Bu soruya gelen herkesin, sadece hile olacaktır gibi isteğe bağlı @Autowired ek açıklama ayarı akılda tutmak için

public class NullFactoryBean implements FactoryBean { 
    private final Class<?> objectType; 

    public NullFactoryBean(Class<?> objectType) { 
     this.objectType = objectType; 
    } 

    @Override 
    public Object getObject() throws Exception { 
     return null; 
    } 

    @Override 
    public Class<?> getObjectType() { 
     return objectType; 
    } 

    @Override 
    public boolean isSingleton() { 
     return false; 
    } 
} 
5

(hiçbir eleme fasulye bulunursa, yani Bahar referans null adlı bırakacaktır). her yerde fasulye bunu yapmak zorunda kalacak

@Autowired(required = false) 
private SomeClass someBean 

Not yukarıda belirtildiği gibi bir boşlukla fabrika oluşturarak daha büyük bir güçlük olabilen başvurulmaktadır.

0

testlerde boş fasulye de böyle enjekte edilebilir: Nihai uygulama fasulye propery ayarlarken Bu muhtemelen çalışacak

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = NullTest.class) 
@Configuration 
public class NullTest { 

    @Bean(name = "em") 
    public IEntityManager em() { return null; } 
    @Bean 
    public PlatformTransactionManager tm() { return null; } 

    @Resource 
    private SomeBean someBean; // this would get em and tm fields autowired to nulls 
İlgili konular