سؤال

دعونا نفترض أن لدينا التالي كود جافا:

public class Maintainer {
   private Map<Enum, List<Listener>> map;

   public Maintainer() {
      this.map = new java.util.ConcurrentHashMap<Enum, List<Listener>>();
   }

   public void addListener( Listener listener, Enum eventType ) {
      List<Listener> listeners;
      if( ( listeners = map.get( eventType ) ) == null ) {
         listeners = new java.util.concurrent.CopyOnWriteArrayList<Listener>();
         map.put( eventType, listeners );
      }
      listeners.add( listener );
   }
}

هذا مقتطف الشفرة ليست سوى قليلا تحسين المستمع نمط حيث كل المستمع يقول ما هو نوع الحدث انها مهتمة في توفير طريقة يحافظ المتزامنة الخريطة من هذه العلاقات.

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

يمكن لأحد أن يقول لي كيف يمكنني Spring_ify_ هذا ؟ ما أريد أن يحققوه هو:
1.تعريف المشرف فصل الربيع الفول.
2.تجعل من ذلك أن جميع أنواع المستمعين سوف تكون قادرة على تسجيل أنفسهم المشرف عبر XML باستخدام addListener الأسلوب.الربيع دكتور ولا جوجل سخية جدا في الأمثلة.

هل هناك طريقة لتحقيق ذلك بسهولة ؟

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

المحلول

ما الخطأ في أن تفعل شيئا من هذا القبيل ما يلي:

تحديد 'مشرف' واجهة مع addListener(المستمع ، Enum) الأسلوب.

إنشاء DefaultMaintainer فئة (على النحو الوارد أعلاه) التي تنفذ معيل.

ثم في كل مستمع من الدرجة, 'حقن' المشرف واجهة (حقن منشئ قد يكون خيار جيد).المستمع ثم يمكن تسجيل نفسه مع المشرف.

بخلاف ذلك, أنا لست 100% واضحة على بالضبط ما صعوبة الخاص بك مع الربيع في هذه اللحظة!:)

نصائح أخرى

قليلا الحمل والولادة (لأن هذا ليس حول الربيع) ولكن هناك شرط سباق في تنفيذ AddListener:

  if( ( listeners = map.get( eventType ) ) == null ) {
     listeners = new java.util.concurrent.CopyOnWriteArrayList<Listener>();
     map.put( eventType, listeners );
  }
  listeners.add( listener );

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

يصلح هذا التغيير:

private Map<Enum, List<Listener>> map;

...

map.put( eventType, listeners );

إلى:

private ConcurrentMap<Enum, List<Listener>> map;

...

map.putIfAbsent( eventType, listeners );
listeners = map.get( eventType );

1) تحديد المشرف فصل الربيع الفول.

معيار الربيع الجملة ينطبق:

<bean id="maintainer" class="com.example.Maintainer"/>

2) تجعل من ذلك أن جميع أنواع المستمعين سوف تكون قادرة على تسجيل أنفسهم المشرف عن طريق XML باستخدام addListener الأسلوب.الربيع دكتور ولا جوجل سخية جدا في الأمثلة.

هذا هو اصعب.لك يمكن أن استخدام MethodInvokingFactoryBean إلى الاتصال بشكل فردي maintainer#addListener, مثل:

<bean id="listener" class="com.example.Listener"/>

<bean id="maintainer.addListener" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="targetObject" ref="maintainer"/>
  <property name="targetMethod" value="addListener"/>
  <property name="arguments">
    <list>
      <ref>listener</ref>
      <value>com.example.MyEnum</value>
   </list>
 </property>
</bean>

ومع ذلك, هذا هو عملي ، ويحتمل أن تكون عرضة للخطأ.حاولت شيئا من هذا القبيل على المشروع ، وخلق الربيع فئة فائدة للمساعدة بدلا من ذلك.ليس لدي شفرة المصدر المتاحة في هذه اللحظة, لذلك سوف تصف كيفية تنفيذ ما فعلت.

1) ريفاكتور الحدث أنواع استمع إلى MyListener واجهة

public interface MyListener extends Listener {
  public Enum[] getEventTypes()
}

الذي يغير طريقة التسجيل إلى

public void addListener(MyListener listener)

2) إنشاء الربيع مساعد الدرجة التي يجد كل ذات الصلة المستمعين في السياق ، يدعو المشرف#addListener لكل مستمع وجدت.وأود أن تبدأ مع BeanFilteringSupport, و أيضا تنفيذ BeanPostProcessor (أو ApplicationListener) التسجيل الفول بعد كل الفاصوليا تم إنشاء مثيل.

قلت "...لا يمكن أن يكون جافا.لانغ.التعداد باعتباره" الشرح المعلمة ..."

أعتقد أنك مخطئ في ذلك.كنت قد استخدمت مؤخرا على مشروع شيئا من هذا القبيل :

public @interface MyAnnotation {
    MyEnum value();
}

شكرا لكم جميعا على الإجابات.الأولى سريعة متابعة جميع الإجابات.
1.(alexvictor) نعم ، هل يمكن أن يكون ملموسة التعداد كما شرح المعلمة ، ولكن ليس java.لانغ.التعداد.
2.الإجابة التي قدمتها flicken هو الصحيح, ولكن للأسف مخيفا بعض الشيء.أنا لست الربيع الخبراء ولكن فعل الأشياء بهذه الطريقة (إنشاء طرق أسهل الربيع الوصول) ويبدو أن مبالغة بعض الشيء ، MethodInvokingFactoryBean الحل.على الرغم من أنني أردت أن أعبر عن خالص شكري على الوقت والجهد.
3.الجواب من خلال فيل هو قليلا غير عادية (بدلا من الحقن المستمع الفول, حقن معيل!), ولكن أعتقد أنظف من كل ما هو متاح.أعتقد أنني سوف تذهب في هذا الطريق.

مرة أخرى الشكر الكبير لكم على مساعدتكم.

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