Sto utilizzando Spring Boot per l'applicazione autonoma Java. Ho un fagiolo che fa uso di un servizio. Voglio iniettare diverse implementazioni di quel servizio in fase di esecuzione, in base a una proprietà in un file di proprietà con Spring (4 per quella materia).Come iniettare servizi diversi in fase di esecuzione in base a una proprietà con Spring senza XML
Questo suona come il modello di fabbrica, ma Spring consente anche di utilizzare annotazioni per risolvere il problema, come questo.
@Autowired @Qualifier("selectorProperty") private MyService myService;
Poi nel file beans.xml Ho un alias, in modo che possa utilizzare la proprietà nel @Qualifier.
<alias name="${selector.property}" alias="selectorProperty" />
E nelle mie diverse implementazioni avrei qualificazioni diverse.
@Component("Selector1")
public class MyServiceImpl1
@Component("Selector2")
public class MyServiceImpl2
application.properties
selector.property = Selector1
selector.property = Selector2
Mentre per quanto riguarda il modello di fabbrica, in primavera è possibile utilizzare ServiceLocatorFactoryBean per creare una fabbrica che darebbe la stessa funzionalità.
<bean
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"
id="myServiceFactory">
<property
name="serviceLocatorInterface"
value="my.company.MyServiceFactory">
</property>
</bean>
public interface MyServiceFactory
{
MyService getMyService(String selector);
}
E quindi nel bean è possibile utilizzare qualcosa di simile per ottenere la corretta implementazione in fase di esecuzione in base al valore della proprietà.
@Value("${selector.property}") private String selectorProperty;
@Autowired private MyServiceFactory myServiceFactory;
private MyService myService;
@PostConstruct
public void postConstruct()
{
this.myService = myServiceFactory.getMyService(selectorProperty);
}
Ma il problema con questa soluzione è che non riuscivo a trovare un modo per evitare l'uso di XML per definire la fabbrica, e vorrei utilizzare solo le annotazioni.
Quindi la domanda sarebbe, c'è un modo per utilizzare il ServiceLocatorFactoryBean (o qualcosa di equivalente) utilizzando solo le annotazioni, o sono costretto a usare il modo @Autowired @Qualifier se io non voglio definire i fagioli in XML? O esiste un altro modo per iniettare servizi diversi in fase di esecuzione in base a una proprietà con Spring 4 che evita XML? Se la tua risposta è semplicemente usare lo @Autowired @Qualifier
con l'alias, ti preghiamo di spiegare perché è meglio che usare un modello di fabbrica ben noto.
L'utilizzo dell'XML in più mi costringe a utilizzare @ImportResource("classpath:beans.xml")
nella mia classe Launcher, che preferirei non utilizzare.
Grazie.
Hai provato @Qualifier ("$ {selector.property}")? È possibile nominare dinamicamente i bean, quindi forse è possibile impostare qualificatori anche in questo modo ... Non ho provato me stesso però .. – Nadir
L'ho provato, ma non funziona. @Autowired @Qualifier ("$ {selector.property}") si risolve in null. Ha bisogno dell'alias come passo intermedio. Grazie comunque per il suggerimento. –
Non sei sicuro, cosa stai cercando di archiviare, hai guardato la separazione della configurazione di primavera con i profili? – mavarazy