Sono nuovo di Guice e sto lavorando a un'applicazione con una grande quantità di codice legacy. Ha diverse classi che assomigliano a questo:Migrazione dell'applicazione per utilizzare Guice - come iniettare le transazioni in oggetti esistenti?
public final class DataAccessClass {
private Transaction txn;
@Inject //This was just added
public DataAccessClass(/* injectable parameters */, Transaction txn) {
this.txn = txn;
}
//Maybe add @Inject here to set a new transaction when it changes?
public void setTransaction(Transaction txn) {
this.txn = txn;
}
public void writeData(/* parameters for data to be written */) {
//Write data using the current instance of 'txn'
}
}
E 'abbastanza chiaro come utilizzare Guice di legare le istanze che non cambiano mai, ma per quanto riguarda le istanze che cambiano (transazioni vale a dire)? C'è un modo per me di usare Guice per iniettare una diversa istanza di Transazione quando cambia? noti che l'istanza transazione non è una delle operazioni/primavera JPA/Hibernate ben supportato
L'approccio meno invasivo posso pensare (evitando la necessità di migrare ogni classe che utilizza una transazione immediatamente) userebbe Guice per iniettare Transaction solo durante l'istanziazione di oggetti, e manterrei il codice applicativo esistente che aggiorna le transazioni quando necessario. Ad esempio, questo provider potrebbe essere usato per iniettare nuovi oggetti con l'istanza corrente di transazione:
public final class TransactionProvider implements Provider<Transaction> {
/** Nullable transaction that should be used for all operations at the moment */
private Transaction txn;
public TransactionProvider(Transaction txn) {
this.txn = txn;
}
/**
* @param txn Nullable transaction to use for all operations at the moment
*/
public void setTransaction(Transaction txn) {
this.txn = txn;
}
/* Provider methods */
public Transaction get() {
return this.txn;
}
}
logica applicazione sarebbe simile a questa:
public final class Application {
private final Provider<Transaction> transactionProvider;
private final DataAccessClass dao; //Instance provided by Guice
public void scopedOperation() {
//Use a fresh transaction for this operation
final Transaction txn = ...;
//Make transaction available to Guice (for new objects) and to legacy (already-instantiated) DAO classes
this.transactionProvider.setTransaction(txn);
this.dao.setTransaction(txn); //Legacy approach - can this be updated?
//Do some kind of data operation under the scope of the current transaction
try {
this.dao.writeData(...);
} catch (Exception e) {
txn.abort();
throw new RuntimeException("Operation failed", e);
}
//The operation is over now
this.txn.commit();
}
ci sono altri modi per aggiornare l'istanza di Transazione che le classi esistenti usano senza dover migrare ogni classe in una volta sola?
Grazie - sembra che funzioni. Buon punto sul refactoring delle classi precedenti per richiedere Transazioni da Guice - sembra che sarebbe solo una piccola modifica per ogni classe legacy, e sarebbe probabilmente molto più semplice rispetto all'utilizzo di 2 sistemi per la gestione delle transazioni. –