2016-04-05 14 views
5

Baharı yeniden denemeyi deniyorum ve garip bir konuyla karşılaşıyorum. Yeniden Deneme Denetleyicisindeki bir yöntemde yeniden deneme notunu kullandığımda, yeniden deneme çalışmaz. Ama bu yöntemi ayrı bir hizmet sınıfına taşırsam çalışır.Springcory, RestController'de çalışmıyor

@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"; 
     } 
    } 
} 

Ama şu yapar: Aşağıdaki kod çalışmaz denetleyici kullanıldığında @Retryable neden çalışmadığını

@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"; 
     } 
    } 
} 

Sorum şu?

cevap

4

Gördüğünüz sorun, getInfo() yönteminizi nasıl aradığınızdan kaynaklanmaktadır.

İlk örnekte, getInfo() numaralı telefonu aynı bahar yönetilen fasulye içinden çağırıyorsunuz. İkinci örnekte, farklı bir yaylı yönetilen fasulyeden getInfo()'u arıyorsunuz. Bu ayrım ince, ama çok önemlidir ve sorunlarınıza neyin yol açtığı çok muhtemeldir.

@Retryable ek açıklamasını kullandığınızda, Spring özel çekirdeğinizin etrafında özel bir işlem yapabilmeleri için orijinal çekirdeğinizin etrafında bir proxy oluşturur. Bu özel durumda, Spring, gerçek yönteminize bir çağrı gönderecek, RuntimeException'ları yakalayabilecek ve @Retryable ek açıklamanızın yapılandırmasına göre yönteminizin çağrılmasını yeniden deneyecek bir Tavsiye uygulamaktadır.

Bu vekilin sizin için önemli olmasının nedeni, yalnızca harici arayanların vekil tavsiyesini görmeleridir. Fasonuzun proksiye olduğu bilgisi yoktur ve sadece yöntemlerinin çağrıldığını bilir (proxy tavsiyesi ile). Çekirdeğiniz kendi başına bir yöntem çağırdığında, başka bir proxy işlemi söz konusu değildir, bu nedenle yeniden deneme aslında gerçekleşmez.