Ho un set di classi con uno schema di inizializzazione complesso. Fondamentalmente, comincio con l'interfaccia di cui ho bisogno per ottenere una sospensione, e poi faccio un sacco di chiamate, e finisco con un oggetto che implementa quell'interfaccia.Spring @Autowiring con bean generici di fabbrica
Per gestire questo, ho creato una classe di fabbrica che può, data un'interfaccia, produrre l'oggetto finale. Ho trasformato questa fabbrica in un bean e in XML ho specificato i miei vari bean di servizio come istanziati tramite questo oggetto factory con un parametro dell'interfaccia che implementeranno.
Questo funziona benissimo e ottengo esattamente esattamente i chicchi di cui ho bisogno. Sfortunatamente, mi piacerebbe accedervi dalle mie classi controller, che vengono scoperte tramite la scansione dei componenti. Io uso @Autowired qui, e sembra che Spring non abbia idea di che tipo di oggetto siano, e dal momento che @Autowired funziona per tipo, io sono SOL.
Utilizzare @Resource (name = "beanName") qui funzionerebbe perfettamente, tuttavia sembra strano usare @Resource per alcuni bean e @Autowired per altri.
C'è un modo per far sapere a Spring quale interfaccia verrà creata dalla fabbrica per ciascuno di questi bean senza avere un metodo factory diverso per ogni tipo?
Sto usando Spring 2.5.6, a proposito, altrimenti avrei solo JavaConfig il tutto e non pensarci più.
classe di fabbrica:
<T extends Client> T buildService(Class<T> clientClass) {
//Do lots of stuff with client class and return an object of clientClass.
}
contesto app:
<bean id="serviceFactoryBean" class="com.captainAwesomePants.FancyFactory" />
<bean id="userService" factory-bean="serviceFactoryBean" factory-method="buildService">
<constructor-arg value="com.captain.services.UserServiceInterface" />
</bean>
<bean id="scoreService" factory-bean="serviceFactoryBean" factory-method="buildService">
<constructor-arg value="com.captain.services.ScoreServiceInterface" />
</bean>
mio controller:
public class HomepageController {
//This doesn't work
@Autowired @Qualifier("userService") UserServiceInterface userService;
//This does
@Resource(name="scoreService") ScoreServiceInterface scoreService;
}
Mi piace. All'inizio mi stavo allontanando da FactoryBeans, ma onestamente sembra che faranno esattamente quello che voglio che facciano. –
@CaptainAwesomePants: tendo a mantenere le mie implementazioni 'FactoryBean' il più sottili possibile, facendole delegare a un'altra classe che non usa l'API Spring. Si potrebbe fare lo stesso, delegare semplicemente al proprio 'serviceFactoryBean' esistente. – skaffman
@skaffman: Quindi in questo caso ci dovrebbero essere altrettante implementazioni di 'FactoryBean' come numero di variazioni dei tipi di ritorno. Will Spring eseguirà il rilevamento del tipo corretto se vengono aggiunti due metodi aggiuntivi alla fabbrica 'UserServiceInterface buildUserService() {return buildService (UserServiceInterface.class); } 'e' ScoreServiceInterface buildScoreService() {return buildService (ScoreServiceInterface.class); } '(e il contesto viene ri-sintonizzato per usarli)? –