سؤال

أنا أستخدم Java 1.4 مع Log4J.

تتضمن بعض التعليمات البرمجية الخاصة بي إجراء تسلسل وإلغاء تسلسل كائنات القيمة (POJOs).

يعلن كل من POJOs الخاص بي عن وجود مسجل بـ

private final Logger log = Logger.getLogger(getClass());

يشكو المُسلسل من أن org.apache.log4j.Logger غير قابل للتسلسل.

هل ينبغي أن أستخدم

private final transient Logger log = Logger.getLogger(getClass());

بدلاً من؟

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

المحلول

ماذا عن استخدام مسجل ثابت؟أو هل تحتاج إلى مرجع مسجل مختلف لكل مثيل للفئة؟لا يتم إجراء تسلسل للحقول الثابتة بشكل افتراضي؛يمكنك الإعلان بشكل صريح عن الحقول التي سيتم إجراء تسلسل لها باستخدام مجموعة نهائية خاصة وثابتة من ObjectStreamField اسم الشيئ serialPersistentFields. راجع وثائق أوراكل

المحتوى المضاف:كما تستخدم getLogger(getClass()), ، سوف تستخدم نفس المسجل في كل حالة.إذا كنت تريد استخدام مسجل منفصل لكل مثيل، فيجب عليك التمييز بين اسم المسجل في طريقة getLogger().على سبيل المثالgetLogger(getClass().getName() + hashCode()).يجب عليك بعد ذلك استخدام السمة العابرة للتأكد من عدم إجراء تسلسل للمسجل.

نصائح أخرى

يجب أن يكون المُسجل ثابتًا؛هذا من شأنه أن يجعله غير قابل للتسلسل.

لا يوجد سبب لجعل المسجل غير ثابت، إلا إذا كان لديك سبب قوي للقيام بذلك.

اذا أنت حقًا إذا كنت ترغب في اتباع النهج المؤقت، فسوف تحتاج إلى إعادة تعيين السجل عندما يتم إلغاء تسلسل الكائن الخاص بك.طريقة القيام بذلك هي تنفيذ الطريقة:

 private void readObject(java.io.ObjectInputStream in) 
   throws IOException, ClassNotFoundException;

جافادوكس ل قابل للتسلسل لديه معلومات عن هذه الطريقة.

سيبدو تنفيذك له كما يلي:

 private void readObject(java.io.ObjectInputStream in) 
     throws IOException, ClassNotFoundException {
   log = Logger.getLogger(...);
   in.defaultReadObject();
 }

إذا لم تقم بذلك، فسيكون السجل فارغًا بعد إلغاء تسلسل الكائن الخاص بك.

إما أن تعلن أن حقل المسجل الخاص بك ثابت أو عابر.

تضمن كلتا الطريقتين أن طريقة writeObject() لن تحاول كتابة الحقل إلى دفق الإخراج أثناء التسلسل.

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

حاول جعل المسجل ثابتًا بدلاً من ذلك.ومن ثم لا يتعين عليك الاهتمام بالتسلسل لأنه يتم التعامل معه بواسطة مُحمل الفصل.

من الأفضل التعامل مع هذه الأنواع من الحالات، خاصة في EJB، عبر الحالة المحلية للخيط.عادةً ما تكون حالة الاستخدام مثل أن لديك معاملة معينة تواجه مشكلة وتحتاج إلى رفع مستوى التسجيل لتصحيح الأخطاء لهذه العملية حتى تتمكن من إنشاء تسجيل تفصيلي لعملية المشكلة.احمل بعض الحالة المحلية لمؤشر الترابط عبر المعاملة واستخدمها لتحديد المُسجل الصحيح.بصراحة، لا أعرف أين سيكون من المفيد تعيين المستوى على مثيل في هذه البيئة لأن تعيين المثيلات في المعاملة يجب أن يكون وظيفة على مستوى الحاوية، فلن يكون لديك فعليًا التحكم في المثيل الذي يتم استخدامه في معاملة معينة على أي حال.

حتى في الحالات التي تتعامل فيها مع DTO، ليس من الجيد عمومًا تصميم نظامك بطريقة تتطلب مثيلًا محددًا لأن التصميم يمكن أن يتطور بسهولة بطرق تجعل ذلك خيارًا سيئًا.يمكنك أن تأتي بعد شهر من الآن وتقرر أن اعتبارات الكفاءة (التخزين المؤقت أو أي تحسين آخر لتغيير دورة الحياة) ستكسر افتراضك حول تعيين المثيلات إلى وحدات عمل.

إذا كنت تريد أن يكون المسجل لكل مثيل، فنعم، قد ترغب في جعله مؤقتًا إذا كنت ستقوم بإجراء تسلسل للكائنات الخاصة بك.مسجلات Log4J غير قابلة للتسلسل، وليس في إصدار Log4J الذي أستخدمه على أي حال، لذلك إذا لم تجعل حقول المسجل الخاصة بك مؤقتة، فستحصل على استثناءات عند التسلسل.

أدوات التسجيل غير قابلة للتسلسل لذا يجب عليك استخدام عابر عند تخزينها في حقول المثيلات.إذا كنت ترغب في استعادة المسجل بعد إلغاء التسلسل، فيمكنك تخزين المستوى (السلسلة) داخل الكائن الخاص بك والذي يتم إجراء تسلسل له.

هناك أسباب وجيهة لاستخدام مسجل المثيلات.إحدى حالات الاستخدام الجيدة جدًا هي أنه يمكنك إعلان المُسجل في فئة فائقة واستخدامه في جميع الفئات الفرعية (الجانب السلبي الوحيد هو أن السجلات من الفئة الفائقة تُنسب إلى الفئة الفرعية ولكن من السهل عادةً ذلك) أنظر لهذا).

(كما ذكر الآخرون، استخدم ثابتًا أو عابرًا).

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