दुरुपयोग न करें निजी क्षेत्र प्रतिबिंब द्वारा निर्धारित / निर्धारित करते हैं
परावर्तन का उपयोग करना जैसा कि कई उत्तरों में किया गया है, कुछ ऐसा है जिससे हम बच सकते हैं।
यह एक छोटी सी कीमत यहाँ लाता है जबकि यह कई कमियाँ प्रस्तुत करता है:
- हम केवल रनटाइम पर प्रतिबिंब मुद्दों का पता लगाते हैं (उदा: फ़ील्ड अब मौजूद नहीं हैं)
- हम एन्कैप्सुलेशन चाहते हैं लेकिन एक अपारदर्शी वर्ग नहीं जो निर्भरता को छुपाता है जो दिखाई देनी चाहिए और कक्षा को अधिक अपारदर्शी और कम परीक्षण योग्य बनाना चाहिए।
- यह खराब डिजाइन को प्रोत्साहित करता है। आज आप एक घोषणा करते हैं
@Value String field
। कल आप उन्हें 5
या 10
उस कक्षा में घोषित कर सकते हैं और आपको शायद यह भी पता नहीं होगा कि आप कक्षा के डिजाइन को कम करते हैं। इन फ़ील्ड्स (जैसे कंस्ट्रक्टर) को सेट करने के लिए एक अधिक दृश्यमान दृष्टिकोण के साथ, आप इन सभी फ़ील्ड्स को जोड़ने से पहले दो बार सोचेंगे और आप संभवतः उन्हें किसी अन्य वर्ग में उपयोग करेंगे और उपयोग करेंगे @ConfigurationProperties
।
अपनी कक्षा को एकात्मक और एकीकरण दोनों में परीक्षण योग्य बनाएं
अपने स्प्रिंग कंपोनेंट क्लास के लिए दोनों सादे यूनिट टेस्ट (जो कि एक रनिंग स्प्रिंग कंटेनर के बिना है) और इंटीग्रेशन टेस्ट लिखने में सक्षम होने के लिए, आपको इस क्लास को स्प्रिंग के साथ या उसके बिना उपयोग करने योग्य बनाना होगा।
एक इकाई परीक्षण में कंटेनर को चलाने की आवश्यकता नहीं होने पर यह एक बुरा अभ्यास है जो स्थानीय बिल्ड को धीमा कर देता है: आप ऐसा नहीं चाहते हैं।
मैंने यह उत्तर इसलिए जोड़ा क्योंकि यहाँ कोई भी उत्तर इस भेद को नहीं दिखाता है और इसलिए वे व्यवस्थित रूप से एक चल रहे कंटेनर पर भरोसा करते हैं।
इसलिए मुझे लगता है कि आपको इस गुण को वर्ग के आंतरिक रूप में परिभाषित करना चाहिए:
@Component
public class Foo{
@Value("${property.value}") private String property;
//...
}
एक निर्माण पैरामीटर में जिसे वसंत द्वारा इंजेक्ट किया जाएगा:
@Component
public class Foo{
private String property;
public Foo(@Value("${property.value}") String property){
this.property = property;
}
//...
}
इकाई परीक्षण उदाहरण
आप Foo
स्प्रिंग के बिना इंस्टेंट कर सकते हैं और property
कंस्ट्रक्टर को धन्यवाद के लिए किसी भी मूल्य को इंजेक्ट कर सकते हैं :
public class FooTest{
Foo foo = new Foo("dummyValue");
@Test
public void doThat(){
...
}
}
एकीकरण परीक्षण उदाहरण
आप को यह आसान तरीका धन्यवाद में स्प्रिंग बूट के साथ संदर्भ में संपत्ति इंजेक्शन लगाने के कर सकते हैं properties
की विशेषता @SpringBootTest
:
@SpringBootTest(properties="property.value=dummyValue")
public class FooTest{
@Autowired
Foo foo;
@Test
public void doThat(){
...
}
}
आप विकल्प के रूप में उपयोग कर सकते हैं @TestPropertySource
लेकिन यह एक अतिरिक्त एनोटेशन जोड़ता है:
@SpringBootTest
@TestPropertySource("property.value=dummyValue")
public class FooTest{ ...}
स्प्रिंग के साथ (स्प्रिंग बूट के बिना), यह थोड़ा और अधिक जटिल होना चाहिए लेकिन जैसा कि मैंने लंबे समय से स्प्रिंग बूट के बिना स्प्रिंग का उपयोग नहीं किया था, मैं एक बेवकूफ बात कहना पसंद नहीं करता।
एक साइड नोट के रूप में: यदि आपके पास @Value
सेट करने के लिए कई फ़ील्ड हैं, तो उन्हें एनोटेट के साथ वर्ग में निकालना @ConfigurationProperties
अधिक प्रासंगिक है क्योंकि हम बहुत सारे तर्कों के साथ एक निर्माता नहीं चाहते हैं।