2013-03-05 17 views
5

Ho due fagioli. Entrambi implementano la funzione di mailing. Uno funziona solo quando è distribuito su un server delle applicazioni. L'altro è usato per i test.Cablaggio di default molla con profilo

Abbiamo un profilo per ogni sviluppatore e ambiente. Voglio cablare il bean di test solo quando effettivamente collaudo. L'altro bean dovrebbe essere usato quando non viene testato. Come posso archiviare questo?

@Component 
@Profile("localtest") 
public class OfflineMail implements Mailing {} 

Soluzione avvicina:

L'utilizzo di "default" Ho letto da qualche parte, ma sembra che ci sia alcun ripiego per "default" per un profilo come "dev":

@Component 
@Profile("default") 
public class OnlineMail implements Mailing {} 

-> Eccezione per nessun bean per il cablaggio trovato.

Lasciando il profilo out:

@Component 
public class OnlineMail implements Mailing {} 

-> genera un'eccezione unica durante l'esecuzione del "localtest" profilo.

Aggiunta di tutti i profili:

@Component 
@Profile("prod") 
@Profile("integration") 
@Profile("test") 
@Profile("dev1") 
@Profile("dev2") 
@Profile("dev3") 
... 
public class OnlineMail implements Mailing {} 

Questo è in realtà di lavoro, tuttavia i nostri sviluppatori non sono numerati usano "dev <WindowsLogin>" e aggiungendo i profili, può funzionare per un fagiolo, ma si otterrà nei guai quando lo si utilizza per diversi fagioli, dato che questo diventa decisamente brutto.

L'utilizzo di qualcosa come @Profile ("! Localtest") non sembra funzionare altrettanto bene.

Qualcuno conosce un modo migliore per ottenere un "filo per impostazione predefinita se non viene trovato un bean specifico"?

+0

'@ Component' senza' @ Profile' deve essere di fagioli di default, se non è cablata. Hai provato a evitare un'eccezione univoca con il nome dell'impostazione del componente? Voglio dire, '@Component (" mail ")' con '@Profile (" localtest ")' e senza di esso? – n1ckolas

risposta

5

Ho finalmente trovato una soluzione facile.

La posta online è appena cablata per impostazione predefinita.

@Component 
public class OnlineMail implements Mailing {} 

Utilizzando la @Primary annotazione la posta in linea ha la precedenza sul OnlineMail ed evita l'unica eccezione.

@Component 
@Profile("localtest") 
@Primary 
public class OfflineMail implements Mailing {} 
2

Prova questo:

@Component 
@Profile("production") 
public class OnlineMail implements Mailing {} 

@Component 
@Profile("localtest") 
public class OfflineMail implements Mailing {} 

Poi eseguire i test utilizzando @ActiveProfiles ("localtest") ed eseguire la produzione di ambiente utilizzando la "produzione" come DI DEFAULT profilo.

Anche io spero nella prossima versione di Primavera ActiveProfilesResolver verrà introdotto SPR-10338 - potrebbe essere utile per voi (per evitare "dev1", "dev2" e così via).

+0

Non capisco il motivo di questa soluzione. Stiamo impostando l'ambiente corretto ovunque si distribuisca l'applicazione. Quindi Spring non dovrebbe caricare il valore predefinito, dovrebbe? E non sono sicuro su come separare l'impostazione predefinita per i test poiché la risorsa di produzione sarà anche nel nostro file di test. –

+0

Ci sono due tipi di profili - predefiniti

+0

Quindi, è meglio evitare l'uso predefinito (vuoto) profilo a molla per qualsiasi bean che abbia già una simulazione - usa i profili "produzione" e "localtest". E su start selezionare richiesto - utilizzando @ActiveProfiles per test e 'pring.profiles.default' o'pring.profiles.active 'per il server –

0

Primavera supporta iniettare il fagiolo da @profile molto bene:

interface Talkative { 
    String talk(); 
} 

@Component 
@Profile("dev") 
class Cat implements Talkative { 
     public String talk() { 
     return "Meow."; 
    } 
} 

@Component 
@Profile("prod") 
class Dog implements Talkative { 
    public String talk() { 
     return "Woof!"; 
    } 
} 

Opere in unit test

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:applicationContex-test.xml"}) 
@ActiveProfiles(value = "dev") 
public class InjectByDevProfileTest 
{ 
    @Autowired 
    Talkative talkative; 

    @Test 
    public void TestTalkative() { 
     String result = talkative.talk(); 
     Assert.assertEquals("Meow.", result); 

    } 
} 

Opere in main():

@Component pubblico class Main {

 public static void main(String[] args) { 
      // Enable a "dev" profile 
      System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "dev"); 
      ApplicationContext context = 
        new ClassPathXmlApplicationContext("applicationContext.xml"); 
      Main p = context.getBean(Main.class); 
      p.start(args); 
     } 

     @Autowired 
     private Talkative talkative; 

     private void start(String[] args) { 
      System.out.println(talkative.talk()); 
     } 
    } 

Controllare questo per il codice Demo: https://github.com/m2land/InjectByProfile

Problemi correlati