2016-04-05 5 views
5

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

@RestController 
public class HelloController { 

    @RequestMapping(value = "/hello") 
    public String hello() { 
     return getInfo(); 
    } 

    @Retryable(RuntimeException.class) 
    public String getInfo() { 
     Random random = new Random(); 
     int r = random.nextInt(2); 
     if (r == 1) { 
      throw new RuntimeException(); 
     } else { 
      return "Success"; 
     } 
    } 
} 

लेकिन निम्नलिखित है:

@RestController 
public class HelloController { 

    @Autowired 
    private SomeService service; 

    @RequestMapping(value = "/hello") 
    public String hello() { 
     String result = service.getInfo(); 
     return result; 
    } 
} 

@Service 
public class SomeService { 

    @Retryable(RuntimeException.class) 
    public String getInfo() { 
     Random random = new Random(); 
     int r = random.nextInt(2); 
     if (r == 1) { 
      throw new RuntimeException(); 
     } else { 
      return "Success"; 
     } 
    } 
} 

मेरा प्रश्न है क्यों @Retryable काम नहीं कर रहा है जब नियंत्रक में प्रयोग किया जाता?

उत्तर

4

जो समस्या आप देख रहे हैं वह इस कारण है कि आप अपनी getInfo() विधि को कैसे कॉल कर रहे हैं।

पहले उदाहरण में, आप उसी वसंत प्रबंधित बीन के भीतर से getInfo() पर कॉल कर रहे हैं। दूसरे उदाहरण में आप एक अलग वसंत प्रबंधित बीन से getInfo() पर कॉल कर रहे हैं। यह भेद सूक्ष्म है, लेकिन बहुत महत्वपूर्ण है, और यह आपके मुद्दों के कारण होने की संभावना है।

जब आप @Retryable एनोटेशन का उपयोग करते हैं, तो वसंत आपके मूल बीन के चारों ओर एक प्रॉक्सी बना रहा है ताकि वे विशेष परिस्थितियों में विशेष संचालन कर सकें। इस विशिष्ट मामले में, स्प्रिंग एक सलाह लागू करती है जो आपके @Retryable एनोटेशन की कॉन्फ़िगरेशन के अनुसार RuntimeException को पकड़ने और आपकी विधि के आमंत्रण को पुनः प्रयास करने के लिए आपकी वास्तविक विधि पर एक कॉल का प्रतिनिधित्व करेगी।

आपके मामले में इस प्रॉक्सी मामलों का कारण यह है कि केवल बाहरी कॉलर्स प्रॉक्सी सलाह देखते हैं। आपके बीन को कोई ज्ञान नहीं है कि यह प्रॉक्सी है, और केवल यह जानता है कि इसकी विधियों को बुलाया जा रहा है (प्रॉक्सी सलाह द्वारा)। जब आपका बीन स्वयं पर एक विधि कहता है, तो आगे कोई प्रॉक्सी नहीं होता है, यही कारण है कि पुनः प्रयास वास्तव में नहीं होता है।

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