سؤال

هل هناك طريقة في الربيع يمكنني أن أتمكن من ملء قائمة مع جميع الفاصوليا من نوع وأي من أنواعها الفرعية؟ لدي طريقة STERTER تبدو وكأنها:

setMyProp(List<MyType> list)

وأود أن أتوفرة في أي فاصوليا من mytype وجميع الفئات الفرعية من mytype.

شكرا، جيف

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

المحلول

نعم، يمكنك القيام بذلك. يقول مستندات الربيع:

من الممكن أيضا توفير جميع الفول من نوع معين من ApplicationContext عن طريق إضافة التوضيح إلى حقل أو طريقة تتوقع مجموعة من هذا النوع.

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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  

    <bean class="test.Test.TypeB"/>
    <bean class="test.Test.TypeC"/>
    <bean class="test.Test.TypeD"/>
</beans>

واختبار الوحدة هذه:

package test;

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {

    private @Autowired List<TypeA> beans;

    @org.junit.Test
    public void test() {
        assertNotNull(beans);
        assertEquals(2, beans.size());
        for (TypeA bean : beans) {
            assertTrue(bean instanceof TypeA);
        }
    }       

    public static interface TypeA {}
    public static class TypeB implements TypeA {}
    public static class TypeC extends TypeB {}
    public static class TypeD {}

}

لذلك رسميا، أنت من المفترض أن تتلليف TypeA[], ، ليس List<TypeA>, ، ولكن القائمة تعمل بشكل جيد.

نصائح أخرى

إذا كان من المقبول أن تملأ القائمة من رمز التطبيق وليس من داخل ملف تعريف الفول الذي يمكنك استخدامه org.springframework.beans.factory.xml.XmlBeanFactory واسأله "getBeansOfType( MyType.class )"هذا يمنحك جميع الفول من النوع (والبحث عن النوع الفرعي) MyType.

إذا كنت تستطيع استخدام @Autowired داخل الكود المراد تعبئته، يمكنك استخدام الطريقة التي ذكرتها Skaffman بأمان. إذا كنت تصر على تكوين XML هناك مكتبة صغيرة تسمى هيرا لتحقيق هذا. يبدو أن تكوين السيناريو الموضح من قبل هذا:

<bean id="client" class="..">
    <property name="injectDynamicListHere">
        <hera:list class="my.custom.SuperType" />
    </property>
</bean>

سيؤدي ذلك إلى ضخ جميع فاصوليات الربيع على المستوى الأعلى SuperType كما List في الفاصوليا العميل.

إجابة قصيرة: لا.

الإجابة الطويلة: تعمل Java Generics عن طريق محو النوع، مما يعني أنه في وقت التشغيل أن المعلمة هي ببساطة قائمة، وليس قائمة من نوع عام. على هذا النحو، لا يمكنك معرفة أنه من المفترض أن يكون من نوع المعلمة mytype لذلك لن يكون من الممكن تنفيذ هذا السلوك.

يقال أن هناك طرق بديلة للقيام بذلك. يبدو أن الأكثر وضوحا هو الاستماع إلى إنشاء الفول ثم رؤية ما إذا كانت من mytype (أو فئة فرعية) ثم إظهار مرجع.

ربما هناك بضع طرق للقيام بذلك. واحد هو إنشاء الفاصوليا بعد المعالج. وبعد بهذه الطريقة سوف تحصل على إخطار كل فول تم إنشاؤه.

بسبب الرمز القديم وفاتين @ sautowired أنا حلها مثل:

MyBean implements ApplicationContextAware{

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class);
    ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top