2013-02-04 10 views
5

Ho questo fagiolo nel mio config Spring Java:Come sovrascrivere un bean con scope per i test?

@Bean 
@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value=SpringScopes.DESKTOP) 
public BirtSession birtSession() { 
    return new BirtSession(); 
} 

Per i test, ho bisogno di un mock, senza un campo di applicazione (non v'è alcun margine "Desktop" nel test). Ma quando creo una configurazione per la mia prova che importa la configurazione di cui sopra e contiene:

@Bean 
public BirtSession birtSession() { 
    return new MockSession(); 
} 

ottengo un "desktop" fagiolo deriso ambito :-(

Come faccio Primavera "dimenticare" il @Scope ? annotazione

PS:. funziona quando io non uso @Import e utilizzare copia incolla & ma io non voglio farlo

+0

Che tipo di test stai scrivendo? Test unitario? –

+1

Cosa dire dell'annotazione di 'birtSession()' con '@ Primary'? * Alcuni scope * 'DESKTOP' dovranno essere disponibili, ma l'autowiring sceglierà sempre il tuo bean primario. –

+0

@JBNizet: Sì, è un test JUnit che utilizza il 'SpringJUnit4ClassRunner' –

risposta

1

Il problema sembra essere in ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod() che utilizza ScopedProxyCreator.createScopedProxy() metodo statico per creare la definizione bean ambito:

// replace the original bean definition with the target one, if necessary 
     BeanDefinition beanDefToRegister = beanDef; 
     if (proxyMode != ScopedProxyMode.NO) { 
      BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
        new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); 
      beanDefToRegister = proxyDef.getBeanDefinition(); 
    } 

quanto BeanDefinitionHolder restituisce un RootBeanDefinition anziché ConfiguratioClassBeanDenition la definizione ambito delega bean (cioè, la ScopedProxyFactoryBean) non può essere annullato da un'altra classe di configurazione Java.

Una soluzione potrebbe essere dichiarando i fagioli limitate all'ambito di ignorare in un file di configurazione XML e importarlo con @ImportResource.

+0

Sembra un bug/funzionalità. È intenzionale o dovrei segnalarlo come un bug? –

+0

Penso che sia un bug. ConfigurationClassBeanDefinitionReader non dovrebbe registrare RootBeanDefinitions poiché ha la sua classe BeanDefinition per determinare se la definizione del bean è stata creata esternamente. –

+0

Sento che dovresti segnalare questo bug dal momento che sembri sapere di cosa stai parlando :-) Aggiungi l'URL alla risposta o come commento dopo averlo fatto. –

0

il problema non è la primavera mantenendo l'annotazione, il probl em è che Spring tenta prima di analizzare la configurazione "produttiva" e, per farlo, controlla se l'oscilloscopio è disponibile. Spring controlla con entusiasmo gli ambiti. Quindi non arriva mai alla seconda/sovrascrittura della definizione del bean.

creare un ambito di manichino:

import java.util.HashMap; 
import java.util.Map; 
import org.springframework.beans.factory.ObjectFactory; 

public class MockSpringScope implements org.springframework.beans.factory.config.Scope { 

    private Map<String, Object> objects = new HashMap<String, Object>(); 

    @Override 
    public Object get(String name, ObjectFactory<?> objectFactory) { 
     Object result = objects.get(name); 
     if(null == result) { 
      result = objectFactory.getObject(); 
      objects.put(name, result); 
     } 
     return result; 
    } 

    @Override 
    public Object remove(String name) { 
     return objects.remove(name); 
    } 

    @Override 
    public void registerDestructionCallback(String name, Runnable callback) { 
     // NOP 
    } 

    @Override 
    public Object resolveContextualObject(String key) { 
     // NOP 
     return null; 
    } 

    @Override 
    public String getConversationId() { 
     // NOP 
     return null; 
    } 

} 

e registrare che, in quanto ambito "Desktop". Ciò consentirà a Spring di analizzare correttamente la configurazione di produzione.

Problemi correlati