سؤال

أحاول حقن الفاصوليا المحددة في سياق الربيع في مكون إدارة CDI ولكني لست ناجحًا. لا يتم حقن الفول ، وبدلاً من ذلك يتم إنشاء مثيل جديد في كل مرة يجب فيها إجراء الحقن. بيئتي هي Tomcat 7 مع JBoss Weld.

spring applicationcontext straighforward:

<beans>
  ...
  <bean id="testFromSpring" class="test.Test" />
  ...
</bean>

تبدو الفاصوليا المدارة CDI مثل هذا:

@javax.inject.Named("testA")
public class TestA {

  @javax.inject.Inject
  private Test myTest = null;

  ...

  public Test getTest() {
    return this.myTest;
  }

}

هذا هو بلدي faces-config.xml

<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0">
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>
</faces-config>

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

<html>
  ...
  <p>1: <h:outputText value="#{testFromSpring}" /></p>
  <p>2: <h:outputText value="#{testA.test}" /></p>
  ...

أحصل على الإخراج التالي:

1: test.Test@44d79c75
2: test.Test@53f336eb

بعد التحديث:

1: test.Test@44d79c75
2: test.Test@89f2ac63

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

إذن ، ما سبب هذا السلوك؟

كيف يمكنني حقن الفول من سياق الربيع في حبة CDI المدارة؟

لقد حاولت أيضًا استخدام مؤهل باستخدام الاسم المحدد في سياق الربيع ، ولكن الآن يتم إلقاء استثناء يشير إلى أنه لا يمكن العثور على الفاصوليا:

org.jboss.weld.exceptions.DeploymentException: WELD-001408 Injection point has unsatisfied dependencies.  Injection point:  field test.TestA.myTest;  Qualifiers:  [@javax.inject.Named(value=testFromSpring)]

للرمز

@javax.inject.Named("testA")
public class TestA {

  @javax.inject.Inject
  @javax.inject.Named("testFromSpring")
  private Test myTest = null;
هل كانت مفيدة؟

المحلول

Pascal محق في أنه لا يمكنك حقن شيء يديره الربيع في حبة اللحام (أو العكس).

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

إليكم كيف سيبدو.

@Qualifier
@Retention(Runtime)
public @interface SpringBean {
     @NonBinding String name();
}


public class SpringBeanProducer {

    @Produces @SpringBean
    public Object create(InjectionPoint ip) {
         // get the name() from the annotation on the injection point
         String springBeanName = ip.getAnnotations()....

         //get the ServletContext from the FacesContext
         ServletContext ctx = FacesContext.getCurrentInstance()... 

         return WebApplicationContextUtils
              .getRequiredWebApplication(ctx).getBean(springBeanName);
    }
}

ثم يمكنك الحصول على:

@Inject @SpringBean("fooBean")
private Foo yourObject;

ملاحظة: يمكنك جعل ما سبق أكثر آمنة. بدلاً من الحصول على الفول بالاسم ، يمكنك الحصول على النوع العام لنقطة الحقن ، من خلال التفكير ، والبحث عنها في سياق الربيع.

نصائح أخرى

لا أعتقد أن Weld يمكنه حقن شيء لم يتم إدارته (تم إنشاءه) بواسطة Weld (فول الربيع في قضيتك).

هناك أيضًا مشروع JBOSS SNOWDROP. لا أعرف ما إذا كان سيعمل مع JBoss Weld على Tomcat ، فإن الوثائق تصف فقط على JBoss 5 و 6 و 7. وفقًا لـ http://docs.jboss.org/snowdrop/2.0.0.final/html/ch03.html#d0e618 سيتم حقن الفاصوليا المعلنة في jboss-spring.xml في مواقع تحمل علامة spring بدلاً من inject. لا خبرة بنفسي رغم ذلك ، ymmv.

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