CDI

2015-03-04 5 views
5

का उपयोग कर के रूप में http सत्र ऐसा कोड का उपयोग कर का श्रेय मैं कुछ विरासत कोड है कि वस्तुओं डाल दिया है एक सेम के लिए एक http सत्र विशेषता इंजेक्षन करने के लिए:CDI

MyObject object = new MyObject(); 
Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); 
sessionMap.put("attrname", object); 

वर्ष facelets

@ManagedProperty("#{attrname}") 
private MyObject object; 
का उपयोग कर कोड पहुँचा

क्या बीन में इस सत्र विशेषता को इंजेक्ट करने के लिए सीडीआई (@Inject) का उपयोग करने का कोई तरीका है?

सीडीआई का उपयोग करने वाले नए कोड में नियंत्रित वस्तुओं में बनाए जाने वाली वस्तुओं को बनाने और इंजेक्ट करने का बेहतर तरीका क्या है।

उत्तर

7

गेटटर पर @Produces@Named के साथ प्रबंधित सत्र बीन में इसे पकड़ लें।

@SessionScoped 
public class MyObjectProducer implements Serializable { 

    private MyObject myObject; 

    @Produces 
    @Named("attrname") 
    public MyObject getMyObject() { 
     return myObject; 
    } 

    public void setMyObject(MyObject myObject) { 
     this.myObject = myObject; 
    } 

} 

जब आप इसे किसी भी तरह से सेट करते हैं उदा। myObjectProducer.setMyObject(myObject) कहीं और (या शायद एक सीडीआई @Observes घटना), तो आप इसे @Inject @Named का उपयोग करके कहीं भी इंजेक्ट कर सकते हैं।

@Inject 
@Named("attrname") 
private MyObject myObject; 

और हाँ, यह अभी भी ईएल में #{attrname} के माध्यम से सामान्य रूप से उपलब्ध है। और नहीं, यह सेट नहीं होने पर ऑटो-निर्मित नहीं किया जाएगा, यह null रहेगा जब तक कि आप इसे वास्तव में निर्माता वर्ग की संपत्ति के रूप में सेट न करें।


वैकल्पिक रूप से, यदि आप वास्तव में ExternalContext#getSessionMap() के माध्यम से उदाहरण स्थापित करने की विरासत तरह से रखने के लिए करना चाहते हैं (उदाहरण के लिए, क्योंकि यह तीसरी पार्टी है और आप इस तरह यह नहीं बदल सकते हैं), तो आप वैकल्पिक रूप से भी निर्माता यह सीधे वापस करने दे सकते हैं सत्र के नक्शे से:

@SessionScoped 
public class MyObjectProducer implements Serializable { 

    @Produces 
    @Named("attrname") 
    public MyObject getMyObject() { 
     return (MyObject) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("attrname"); 
    } 

} 

हालांकि यह इस तरह के एक मनमाना @WebServlet के रूप में जब एक गैर JSF विरूपण साक्ष्य, में इंजेक्शन काम करने के लिए गारंटी नहीं है, FacesContext#getCurrentInstance() जाहिर null वापसी होगी के रूप में।

+0

अपने त्वरित और पूरा जवाब के लिए आप @BalusC धन्यवाद। –

+2

शायद उत्तर और भी पूर्ण हो सकता है कि निर्माता को कोड कोड से प्रबंधित करने के लिए इस कोड को 'CDI.current() चुनें। (MyObjectProducer.class) .get()' का उपयोग किया जा सकता है। –

1

यह गैर-जेएसएफ और जेएसएफ कलाकृतियों दोनों के लिए जाने का तरीका है।

@Qualifier 
@Retention(RUNTIME) 
@Target({TYPE,METHOD,FIELD,PARAMETER}); 
public @interface SessionAttribute { 

    @NonBinding 
    String value() default ""; 
} 

@ApplicationScope 
public class SessionAttributeService { 

    //Dont worry, this is a proxy, and CDI will ensure that the right one called at the right time. 
    @Inject 
    private HttpServletRequest servletRequest; 

    @Produces 
    @SessionAttribute 
    @RequestScope 
    public String sessionAttribute(final InjectionPoint ip){ 
    final SessionAttribute sa = ip.getAnnotated().getAnnotation(SessionAttribute.class); 
    final HttpSession session = servletRequest.getSession(); 
    return session.getAttribute(sa.value()); 
    } 
} 

और उपयोग के मामले:

@RequestScope 
public class MyServiceBean { 

    @Inject 
    @SessionAttribute("theAttribute") 
    private String attribute; 

} 
+0

यह ओपी की तरह गैर स्ट्रिंग मान इंजेक्शन करने में सक्षम नहीं है। मैं निश्चित रूप से इसे "सत्र विशेषताओं" के लिए "जाने का तरीका" नहीं कहूंगा। – BalusC

+1

वास्तव में @ बालुससी मैंने स्ट्रिंग का उपयोग करके एक उदाहरण दिया है, वह आसानी से उस प्रकार को बदल सकता है जो वह चाहता है ??? – maress

संबंधित मुद्दे