2009-05-21 8 views
7

में परिवर्तनों का निरीक्षण करें। मुझे आश्चर्य है कि अगर वसंत बीन की संपत्ति किसी अन्य बीन की संपत्ति को बाध्य करने का कोई तरीका है तो यदि बाध्य संपत्ति पर कोई भी बदलाव रनटाइम में होता है, तो क्या मुझे उम्मीद है कि बीन की संपत्ति का संदर्भ भी बदल रहा है। मैं थोड़ा कोड स्निपेट के साथ और अधिक समझाऊंगा।एक बीन संपत्ति को किसी अन्य व्यक्ति से कैसे बांधें और स्प्रिंग फ्रेमवर्क

 
<bean id="johnHome" class="example.Contact"> 
    <property name="phone" value="5551333" /> 
</bean> 

<bean id="johnWork" class="example.Contact"> 
    <property name="phone"> 
     <util:property-path path="johnHome.phone" /> 
    </property> 
</bean> 

ठीक है। यह शुरुआती बीन तारों पर काम करता है लेकिन जो मैं चाहता हूं वह संपत्ति को बांधना है ताकि यदि संपत्ति रनटाइम पर बदलती है तो रेफरेंसिंग बीन भी बदल जाता है। अगर मुझे एक रूपक के साथ दिखाना पसंद है तो यह ऐसा प्रतीत होगा।

 
<bean id="johnHome" class="example.Contact"> 
    <property name="phone" value="5551333" /> 
</bean> 

<bean id="johnWork" class="example.Contact"> 
    <property name="phone"> 
     <util:bind path="johnHome.phone" /> 
    </property> 
</bean> 

क्या मैं वसंत की अवधारणा को बहुत अधिक लोड कर रहा हूं या क्या यह बहुत सारी चाल के बिना संभव है?

धन्यवाद ..

उत्तर

0

मुझे नहीं लगता कि तुम क्या कर रहे हैं स्प्रिंग 2.5 में संभव है। यह नए अभिव्यक्ति वाक्यविन्यास का उपयोग करके वसंत 3 में संभव हो सकता है, लेकिन मुझे ऐसा नहीं लगता है।

भले ही यह था, यह भ्रमित हो जाएगा, मुझे लगता है। अपने साझा मूल्य को अपनी कक्षा में चिपकाना बेहतर है और उस वर्ग के उदाहरण को अन्य बीन्स में इंजेक्ट करना है जिसे इसे साझा करने की आवश्यकता है।

0

मैं दो संभावनाओं के बारे में सोच सकता हूं।

एक है (यह एक हैक की तरह है), यदि आपके पास बहुत से बीन्स नहीं हैं जिन्हें आपके उदाहरण में किसी तरह से जोड़ने की आवश्यकता है, तो आप जॉइन वर्क को जॉन होम बीन में और जॉनहोम.सेटफोन में इंजेक्ट कर सकते हैं आप johnWork फोन संपत्ति, की तरह कुछ अद्यतन कर सकते हैं:

public class Contact { 
    private Contact myWorkContact; 
    private String phone; 

    public void setPhone(String phone) { 
     this.phone = phone; 
     if (this.myWorkContact != null) { 
      this.myWorkContact.setPhone(phone); 
     } 
    } 

    public void setWorkContact(Contact c) { 
     this.myWorkContact = c; 
    } 
} 

या आप HomeContact और WorkContact है दोनों एक वर्ग से संपर्क का विस्तार करने और उस के साथ ही इंजेक्शन कर सकता है।

यदि आपके पास टन और टन बीन्स हैं, तो इसकी आवश्यकता होगी (जैसे कि आपका आवेदन वास्तव में संपर्क जानकारी से निपट रहा है), एओपी के साथ (आपको दिए गए उदाहरण के लिए एस्पेक्टजे की आवश्यकता होगी) मुझे लगता है कि आप ऐसा कुछ कर सकते हैं (यदि आप वस्तुओं का एक टन प्राप्त करते हैं, तो यह थोड़ा स्मृति गहन होगा, लेकिन आप देख सकते हैं कि यह कैसा काम करेगा):

चेतावनी: यह वास्तव में जटिल तेज़ हो गया, लेकिन मुझे पूरा यकीन है कि यह काम करेगा तुम्हारे जाने के बाद कुछ अड़चनों

public class Contact { 
    ... 

    private String phone; 
    private String name; 
    private Integer id; 

    public Contact(Integer id, String name, String phone) { 
     this.phone = phone; 
     this.name = name; 
     this.id = id; 
    } 

    public void setPhone(String phone) { 
     this.phone = phone. 
    } 

    //Other getters, setters, etc 

    ... 
} 


@Aspect 
public class ContactPhoneSynchronizer { 
    //there is probably a more efficient way to keep track of contact objects 
    //but right now i can't think of one, because for things like a tree, we need to 
    //be able to identify objects with the same name (John Smith), but that 
    //have different unique ids, since we only want one of each Contact object 
    //in this cache. 

    private List<Contact> contacts = Collections.synchronizedList(new ArrayList<Contact>()); 

    /** 
     This method will execute every time someone makes a new Contact object. 
     If it already exists, return it from the cache in this.contacts. Otherwise, 
     proceed with the object construction and put that object in the cache. 
    **/ 

    @Around("call(public Contact.new(Integer,String,String)) && args(id,name,phone)") 
    public Object cacheNewContact(ProceedingJoinPoint joinPoint, Integer id, String name, String phone) { 
     Contact contact = null; 

     for (Contact c : contacts) { 
      if (id.equals(c.getId()) { 
       contact = c; 
       break; 
      } 
     } 

     if (contact == null) { 
      contact = (Contact) joinPoint.proceed(); 
      this.contacts.add(contact);    
     } 

     return contact; 
    } 

    /**This should execute every time a setPhone() method is executed on 
     a contact object. The method looks for all Contacts of the same 
     name in the cache and then sets their phone number to the one being passed 
     into the original target class. 

     Because objects are passed by reference until you do a reassociation, 
     calling c.setPhone on the object in the cache should update the actual 
     instance of the object in memory, so whoever has that reference will 
     get the updated information. 
    **/ 

    @After("execution(example.Contact.setPhone(String) && args(phone)") 
    public void syncContact(JoinPoint joinPoint, String phone) { 
     Contact contact = joinPoint.getTarget(); 

     for (Contact c : this.contacts) { 
      if (c.getName().equals(contact.getName()) { 
       c.setPhone(phone); 
      } 
     } 
    } 
} 

फिर बाहर काम किया है, वहाँ शायद 100 वा है हाँ आप इसे अनुकूलित कर सकते हैं, क्योंकि मैं इसे अपने सिर के ऊपर से टाइप कर रहा हूं; यही है, अगर आप इस मार्ग को पहली जगह जाना चाहते थे। सिद्धांत रूप में यह काम करना चाहिए लेकिन मैंने इसका परीक्षण नहीं किया है।

वैसे भी, हैप्पी स्प्रिंगिंग!

1

सरल तरीका - उस संपत्ति को एक बीन बनाएं जो दो अन्य बीन्स द्वारा संदर्भित है, उदा। एक स्ट्रिंग मान के लिए एक StringHolder वर्ग है:

public class StringHolder { 
    private String value; 

    // setter and getter elided due to author's lazyness 

} 
1

वसंत के पीछे पूरे विचार है (था?) एक साफ वस्तु उन्मुख सादे पुराने जावा वस्तुओं से मिलकर डिजाइन रखने के लिए और कठिन वस्तु को संभालने के लिए वसंत ढांचे का उपयोग करने के लिए सृष्टि। एओपी के लिए, यह केवल क्रॉस-कटिंग चिंताओं को संभालना चाहिए। मुझे पूरा विश्वास नहीं है कि यह उन मामलों में से एक है जहां एओपी एक अच्छा विचार है।आपका आवेदन एक दूसरे से समन्वयित होने वाले इन फोन नंबरों के व्यवहार पर निर्भर करता है, यह मुख्य कार्यक्षमताओं में से एक है। इस प्रकार, आपके डिजाइन को इसे प्रतिबिंबित करना चाहिए।

शायद इस विशिष्ट समस्या को संभालने का सबसे तार्किक तरीका फोन नंबरों को अपनी कक्षा बनाना है (जो कि यदि आप कभी भी विभिन्न प्रकार के फोन नंबरों को अलग करना चाहते हैं तो भी आसान है)।

आप एक PhoneNumber वस्तु जो एक निर्माता तर्क मानचित्रण तुच्छ हो जाता है के रूप में नंबर लेता है, तो:

<bean id="johnFirstPhone" class="example.PhoneNumber"> 
    <constructor-arg value="5551333" /> 
</bean> 

<bean id="johnHome" class="example.Contact"> 
    <property name="phone" ref="johnFirstPhone" /> 
</bean> 

<bean id="johnWork" class="example.Contact"> 
    <property name="phone" ref="johnFirstPhone" /> 
</bean> 
पाठ्यक्रम कि क्या आप एक स्थिर फ़ाइल में इस तरह के नक्शे चाहते हैं के

अलग बात है, लेकिन चीज इस स्थिति में है, आपको स्पष्ट रूप से केवल एक संदर्भ/सूचक की आवश्यकता है।

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