ترحيل التطبيق لاستخدام الغيار - كيفية حقن المعاملات في الكائنات الموجودة؟

StackOverflow https://stackoverflow.com/questions/951831

  •  11-09-2019
  •  | 
  •  

سؤال

أنا جديد في الغيار، وأنا أعمل ذلك إلى تطبيق مع كمية كبيرة من القانون القديم. لديها عدة فصول تبدو وكأنها هذه:

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'
    }
}

من الواضح جدا كيفية استخدام الغيار لربط مثيلات لا تتغير أبدا، ولكن ماذا عن المثيلات التي تتغير (المعاملات IE)؟ هل هناك طريقة لاستخدام الغيار لحقن مثيل مختلف من المعاملة عندما يتغير؟ لاحظ أن مثيل المعاملات ليست واحدة من معاملات JPA / السبات / الربيع جيدا

ستستخدم المؤهلات الأقل نشاطا في الحد الأدنى (تجنب الحاجة إلى ترحيل كل فئة واستخدام معاملة في وقت واحد) الغواني لحقن المعاملة فقط عند وجود كائنات Instantiating، وأستمر برمز التطبيق الحالي الذي يقوم بتحديث المعاملات عند الضرورة وبعد على سبيل المثال، يمكن استخدام هذا المزود لحقن كائنات جديدة مع المثيل الحالي للمعاملة:

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;
    }
}

منطق التطبيق سوف تبدو مثل هذا:

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();
    }

هل هناك طرق أخرى لتحديث مثيل المعاملة التي تستخدمها الفئات الموجودة دون الحاجة إلى ترحيل كل فئة مرة واحدة؟

هل كانت مفيدة؟

المحلول

إذا فهمت هذا بشكل صحيح، فإن مشكلتك لديها جزءان مستقلان:

  1. باستخدام مثيل المعاملات الصحيحة على فئات الحث
  2. باستخدام مثيل المعاملات الصحيحة على الفصول القديمة.

بالنسبة إلى '1'، يعمل المزود المخصص الخاص بك، لكنني سأخلق نطاق مخصص للحصول على معاملة وربط فئة المعاملات في هذا النطاق. يرى http:/code.google.com/p/google-guice/wiki/customscopes. للحصول على تعليمات حول النطاقات المخصصة.

فيما يتعلق ب "2"، بمجرد أن يكون لديك نطاق مخصص، فإن هذه هي المشكلة المعتادة في استخدام الغيار لتوفير حالات للفصول القديمة. لم تذكر التعليمات البرمجية التي توفر حاليا مثيلات المعاملات إلى الفئات القديمة، ولكن يمكنك فقط تغيير هذه القطعة المعينة لطلب مثيل من الغيار. نظرا لأنك داخل "نطاق المعاملات"، فإن الغطاء يعتني بتوفير الحالة المناسبة.

نصائح أخرى

إلقاء نظرة على الحقن بمساعدة. وبعد لاستخدامها، حدد واجهة ثلاث خط:

public interface DataAccessClassFactory {
  DataAccessClass create(Transaction transaction);
}

... ثم استخدم FactoryProvider ملزمة لربط المصنع:

bind(DataAccessClassFactory.class).toProvider(
    FactoryProvider.newFactory(DataAccessClassFactory.class, DataAccessClass.class));

ثم يمكنك حقن DataAccessClassFactory أينما تحتاج إلى بناء DataAccessClass. وبعد يتم تضمين AssistedInject في Guice 2، على الرغم من أنه يتطلب ملف .jar منفصل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top