سؤال

هل من الممكن إخبار Guice بالاتصال ببعض الطرق (أي init ()) بعد تثبيت كائن من النوع المعطى؟

أبحث عن وظائف مماثلة لشرح التعليقات التوضيحية postconstruct في EJB 3.

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

المحلول

في الواقع ، هذا ممكن.

تحتاج إلى تحديد أ TypeListener للحصول على وظيفة مستمرة. شيء ما على غرار ما يلي في تعريف الوحدة النمطية:

bindListener(Matchers.subclassesOf(MyInitClass.class), new TypeListener() {
    @Override
    public <I> void hear(final TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
        typeEncounter.register(new InjectionListener<I>() {
            @Override
            public void afterInjection(Object i) {
                MyInitClass m = (MyInitClass) i;
                m.init();
            }
        });
    }
});

نصائح أخرى

يمكنك فقط إضافة ملف @Inject التعليقات التوضيحية لك init() طريقة. سيتم تشغيله تلقائيًا بعد إنشاء كائن.

انا يعجبني http://code.google.com/p/mycila/wiki/mycilaguice. هذا يدعم Guice 3 ، بخلاف http://code.google.com/p/guiceyfruit.

Guiceyfruit هل ما ترفعه من أجل الأساليب المشروحة @PostConstruct أو تنفيذ الربيع InitializingBean. من الممكن أيضًا كتابة مستمعيك للقيام بذلك. إليك مثال يدعو الجمهور init() الطريقة بعد إنشاء الكائنات.

import com.google.inject.*;
import com.google.inject.matcher.*;
import com.google.inject.spi.*;

public class MyModule extends AbstractModule {
  static class HasInitMethod extends AbstractMatcher<TypeLiteral<?>> {
    public boolean matches(TypeLiteral<?> tpe) {
      try {
        return tpe.getRawType().getMethod("init") != null;
      } catch (Exception e) {
        return false;
      }
    }

    public static final HasInitMethod INSTANCE = new HasInitMethod();
  }

  static class InitInvoker implements InjectionListener {
    public void afterInjection(Object injectee) {
      try {
        injectee.getClass().getMethod("init").invoke(injectee);
      } catch (Exception e) {
        /* do something to handle errors here */
      }
    }
    public static final InitInvoker INSTANCE = new InitInvoker();
  }

  public void configure() {
    bindListener(HasInitMethod.INSTANCE, new TypeListener() {
      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
        encounter.register(InitInvoker.INSTANCE);
      }
    });
  }
}

يتضمن Gwizard وحدة نمطية (gwizard-services) الذي يوفر خدمات الجوافة بتنسيق صديق للجيش. تمنحك خدمات الجوافة إدارة دورة الحياة في مؤشرات ترابط متوازية.

https://github.com/stickfigure/gwizard

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


class A {
    public A(Dependency1 d1, Dependency2 d2) {...}

    public postConstruct(RuntimeDependency dr) {...}
}

interface AFactory {
    A getInstance(RuntimeDependency dr);
}

class AFactoryImpl implements AFactory {
    @Inject
    public AFactoryImpl(Dependency1 d1, Dependency2 d2) {...}

    A getInstance(RuntimeDependency dr) {
        A a = new A(d1, d2);
        a. postConstruct(dr);
        return a;
    }
}

// in guice module
bind(AFactory.class).to(AFactoryImpl.class)

في حال كنت بحاجة إلى تهيئة كائن باستخدام كائنات أخرى وبعد أن يكون كلاهما جاهزًا (وهو الحال إذا كنت بحاجة إلى تسجيل واحد مع الآخر ويعتمد أيضًا على بعضهما البعض) ، يمكنك بسهولة القيام بذلك على هذا النحو:

public final class ApplicationModule extends AbstractModule {

  @Override
  protected void configure() {
    requestStaticInjection(ApplicationModule.class);
  }

  @Inject
  static void injectApplication(
      ReslSession reslSession,
      Set<Saga> sagas,
      Set<Reaction> reactions
  ) {
    sagas.forEach(reslSession::registerSaga);
    reactions.forEach(reslSession::registerReaction);
  }

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