هل يجب أن أعلن عن جاكسون كائنات كحقل ثابت؟

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

  •  29-09-2019
  •  | 
  •  

سؤال

مكتبة جاكسون ObjectMapper صف دراسي يبدو أن الخيط آمن.

هل هذا يعني أنني يجب أن أعلن ObjectMapper كحقل ثابت مثل هذا

class Me {
    private static final ObjectMapper mapper = new ObjectMapper();
}

بدلا من كحقل على مستوى مثيل مثل هذا؟

class Me {
    private final ObjectMapper mapper = new ObjectMapper();
}
هل كانت مفيدة؟

المحلول

نعم ، هذا آمن وموصى به.

التحذير الوحيد من الصفحة التي أشرت إليها هو أنه لا يمكنك تعديل تكوين الخريطة بمجرد مشاركته ؛ لكنك لا تقوم بتغيير التكوين بحيث يكون هذا جيدًا. إذا كنت بحاجة إلى تغيير التكوين ، فستفعل ذلك من الكتلة الثابتة وسيكون الأمر جيدًا أيضًا.

تعديل: (2013/10)

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

نصائح أخرى

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

Map aPage = mapper.readValue(reader, Map.class);

بجانب ذلك ، لم يكن الأداء جيدًا. عندما استبدلت المتغير الثابت بمتغير قائم على المثيل ، اختفى المماطلة وربع الأداء. تمت معالجة مستندات JSON 2.4 ملايين ملايين ملايين JSON في 40 دقيقة .56sec ، بدلاً من 2.5 ساعة من قبل.

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

باختصار ، يجب تجنب الإحصائيات لأنه يجعل من الصعب كتابة اختبارات الوحدة الموجزة. على سبيل المثال ، مع وجود كائن نهائي ثابت ، لا يمكنك تبديل تسلسل JSON للرمز الوهمي أو NO-OP.

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

في حالة ObjectMapper ، إنه أمر جيد بشكل عام ، فهي ممارسة سيئة ولا توجد ميزة على استخدام نمط المفرد أو انعكاس السيطرة لإدارة كائناتك الطويلة العمر.

خدعة تعلمتها من هذا العلاقات العامة إذا كنت لا ترغب في تعريفه على أنه متغير نهائي ثابت ولكنك تريد توفير القليل من النفقات العامة وضمان مؤشر الترابط الآمن.

private static final ThreadLocal<ObjectMapper> om = new ThreadLocal<ObjectMapper>() {
    @Override
    protected ObjectMapper initialValue() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return objectMapper;
    }
};

public static ObjectMapper getObjectMapper() {
    return om.get();
}

الائتمان للمؤلف.

com.fasterxml.jackson.databind.type.typefactory._hashmapsuperinterfacechain (Hierarchictype)

com.fasterxml.jackson.databind.type.TypeFactory._findSuperInterfaceChain(Type, Class)
  com.fasterxml.jackson.databind.type.TypeFactory._findSuperTypeChain(Class, Class)
     com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(Class, Class, TypeBindings)
        com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(JavaType, Class)
           com.fasterxml.jackson.databind.type.TypeFactory._fromParamType(ParameterizedType, TypeBindings)
              com.fasterxml.jackson.databind.type.TypeFactory._constructType(Type, TypeBindings)
                 com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeReference)
                    com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, TypeReference)

الطريقة _hashmapsuperinterfacechain في الفصل com.fasterxml.jackson.databind.type.typefactory متزامن. أرى الخلاف على نفسه في الأحمال العالية.

قد يكون سببًا آخر لتجنب كائن ثابت

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