जब किसी अन्य बीन के निर्माता को संदर्भित किया जाता है तो @Autowired बीन शून्य होता है


89

नीचे दिखाया गया कोड का एक स्निपेट है जहां मैं अपने ApplicationProperties सेम की कोशिश करता हूं और संदर्भ देता हूं। जब मैं इसे कंस्ट्रक्टर से संदर्भित करता हूं तो यह अशक्त होता है, लेकिन जब दूसरी विधि से संदर्भित किया जाता है तो यह ठीक है। अब तक मुझे अन्य वर्गों में इस स्वत: प्राप्त सेम का उपयोग करने में कोई समस्या नहीं हुई है। लेकिन यह पहली बार है जब मैंने इसे दूसरे वर्ग के कंस्ट्रक्टर में इस्तेमाल करने की कोशिश की है।

कोडप्रोपरेट्टी के नीचे कोड स्निपेट में कंस्ट्रक्टर से कॉल किए जाने पर शून्य होता है लेकिन कन्वर्ट विधि में संदर्भित होने पर यह नहीं है। मैं क्या खो रहा हूँ

@Component
public class DocumentManager implements IDocumentManager {

  private Log logger = LogFactory.getLog(this.getClass());
  private OfficeManager officeManager = null;
  private ConverterService converterService = null;

  @Autowired
  private IApplicationProperties applicationProperties;


  // If I try and use the Autowired applicationProperties bean in the constructor
  // it is null ?

  public DocumentManager() {
  startOOServer();
  }

  private void startOOServer() {
    if (applicationProperties != null) {
      if (applicationProperties.getStartOOServer()) {
        try {
          if (this.officeManager == null) {
            this.officeManager = new DefaultOfficeManagerConfiguration()
              .buildOfficeManager();
            this.officeManager.start();
            this.converterService = new ConverterService(this.officeManager);
          }
        } catch (Throwable e){
          logger.error(e);  
        }
      }
    }
  }

  public byte[] convert(byte[] inputData, String sourceExtension, String targetExtension) {
    byte[] result = null;

    startOOServer();
    ...

नीचे ApplicationProperties से स्निपेट है ...

@Component
public class ApplicationProperties implements IApplicationProperties {

  /* Use the appProperties bean defined in WEB-INF/applicationContext.xml
   * which in turn uses resources/server.properties
   */
  @Resource(name="appProperties")
  private Properties appProperties;

  public Boolean getStartOOServer() {
    String val = appProperties.getProperty("startOOServer", "false");
    if( val == null ) return false;
    val = val.trim();
    return val.equalsIgnoreCase("true") || val.equalsIgnoreCase("on") || val.equalsIgnoreCase("yes");
  }

जवाबों:


179

ऑटोवेयरिंग (ड्यून्स कमेंट से लिंक) किसी ऑब्जेक्ट के निर्माण के बाद होता है। इसलिए वे तब तक सेट नहीं किए जाएंगे जब तक कि कंस्ट्रक्टर पूरा नहीं हो जाता।

यदि आपको कुछ इनिशियलाइज़ेशन कोड चलाने की आवश्यकता है, तो आपको कंस्ट्रक्टर में कोड को एक विधि में खींचने में सक्षम होना चाहिए, और इस पद्धति को एनोटेट करना चाहिए @PostConstruct


3
जैसा कि डॉक्स में कहा गया है - static.springsource.org/spring/docs/2.5.x/api/org/…
Dunes

लिंक के लिए धन्यवाद, मैं इसे आसान खोजने के लिए उत्तर में जोड़ दूंगा।
nicholas.hauschild

2
धन्यवाद, मुझे अभी तक महत्वपूर्ण बयान "फील्ड्स एक बीन के निर्माण के बाद सही इंजेक्ट किया जाता है ..." आया था। मैंने @PostConstruct एनोटेशन की कोशिश की है और यह वही है जो मुझे चाहिए था।
बालों वाली जू

भी @PostConstruct के बारे में एक लिंक पोस्ट करने के लिए अच्छा होगा static.springsource.org/spring/docs/3.0.0.M3/reference/html/...
Timofey

@ टिम धन्यवाद! मैंने स्प्रिंग 3.2 संस्करण के उत्तर लिंक को अपडेट किया, और मैंने आपके लिंक का स्प्रिंग 3.2 संस्करण भी जोड़ा।
nicholas.hauschild

44

निर्माण के समय पर निर्भरता का इंजेक्शन लगाने के लिए आपको अपने निर्माता को इस @Autowiredतरह से घोषणा के साथ चिह्नित करना होगा ।

@Autowired
public DocumentManager(IApplicationProperties applicationProperties) {
  this.applicationProperties = applicationProperties;
  startOOServer();
}

2
वास्तव में मुझे लगता है कि यह पसंदीदा उत्तर होना चाहिए। कंस्ट्रक्टर आधारित निर्भरता इंजेक्शन दृष्टिकोण अनिवार्य घटकों के लिए बहुत अच्छी तरह से अनुकूल है। इस दृष्टिकोण का उपयोग करते हुए वसंत की रूपरेखा घटकों पर चक्रीय निर्भरता का पता लगाने में भी सक्षम होगी (जैसा कि ए बी पर निर्भर करता है, बी सी पर निर्भर करता है, सी ए पर निर्भर करता है)। बसने वाले या स्व-चालित क्षेत्रों का उपयोग करके इंजेक्शन शैली आपके क्षेत्र में पूरी तरह से प्रारंभिक सेम को इंजेक्ट करने में सक्षम है, जिससे चीजें थोड़ी अधिक गड़बड़ हो जाती हैं।
सीकेयोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.