2014-10-22 18 views
22

Bir fabrikada ek açıklamalarla hala yükleme @Component yüklüyorsa, @Autowired var mı? Bulduğum problem, tembel bileşenlerin fabrikada otomatik olarak bağlanmasıyla, fabrika yüklendikten hemen sonra anında temsili açılacak ve bu, tembel bilgi notunu ortadan kaldıracaktır. BöyleAçıklamalarla @Outowired @Lazy @Components'ı elde etmenin en iyi yolu?

@Component 
@Lazy 
public final class CloseableChromeWebDriver 
     extends ChromeDriver 
     implements DisposableBean { 
... 
} 

@Component 
@Lazy 
public final class CloseableFirefoxWebDriver 
     extends FirefoxDriver 
     implements DisposableBean { 
... 
} 

O

bunlardan biri oluşturulduğunda her
  • , tarayıcı penceresi açılır çünkü tembel olması önemlidir olarak

    Ben tanımladığınız birkaç tembel fasulye.

  • Veriye dayalı testlerim bunlardan herhangi birine veya tümüne ihtiyaç duyuyor olabilir ya da gerektirmeyebilir, yani bir çalışma Firefox olabilir ya da Firefox ve Chrome gerektirebilir.
  • Bu daha önemlidir çünkü aslında altı tane fasulyem var - Firefox, Chrome, IE, Uzak Firefox, Uzak Chrome, Uzak IE.
  • Eğer testlerim bunlardan sadece birini kullanıyorsa, o zaman sadece bir tarayıcının göstermesini istiyorum, hepsini değil.

Ben istenen tarayıcı almak için Fabrikası var, ancak herhangi bir sınıf fabrikası kullanılan her, autowired fasulye tüm bakılmaksızın aslında istendi bakılmaksızın, hemen örneğinin oluşturulmasını çünkü bu benim ilk girişimi başarısız oldu. Anlıyorum çünkü sınıf bir kez örneklendiğinde, ona ait tüm örnek değişkenleri örneklendirmelidir. Yani burada

@Component 
public final class WebDriverFactory { 
    @Autowired 
    private CloseableChromeWebDriver chromeWebDriver; 
    @Autowired 
    private CloseableFirefoxWebDriver firefoxWebDriver; 

    public synchronized WebDriver getWebDriver(final Browser browser) { 
    // get whatever webdriver is matched by the enum Browser. 
    } 
} 

uygulama bağlamında yoluyla fasulye isteyerek tembel yükleme sağlamaktır benim ikinci yaklaşımdır:

@Component 
public final class WebDriverFactory { 
    private CloseableChromeWebDriver chromeWebDriver; 
    private CloseableFirefoxWebDriver firefoxWebDriver; 
    @Autowired 
    private ApplicationContext appContext; 

    public synchronized WebDriver getWebDriver(final Browser browser) { 
     WebDriver driver = null; 
     switch (browser) { 
     case FIREFOX: 
      if (firefoxRemoteWebDriver == null) { 
       firefoxRemoteWebDriver = appContext.getBean("closeableRemoteFirefoxWebDriver", 
        CloseableRemoteFirefoxWebDriver.class); 
      } 
      driver = firefoxRemoteWebDriver; 
      break; 
     // etc... 
     return driver; 
    } 
} 

Bu yaklaşım benim hedefe ulaşır, ama gerçekten faydasını olumsuzlar hissetmek ek açıklamaları kullanarak. Bunu başarmak için tamamen ek açıklama yolu var mı?

  • JDK 6
  • Bahar 3.2.6.RELEASE
  • Hiçbir xml, sadece ek açıklamalar.
+0

Şüphesiz '@ Lazy' özniteliği, fasulyenin tanımına değil, fasulyenin kullanıcısına gider. Bu yüzden, o lazerin tembel yüklü olması için ihtiyaç duyduğu her yere 'Lazy'yi koymanızı beklerim. EVERYWHERE ise, ilk kullanıldığında fasulye yaratılacaktır. –

+0

@AshleyFrieze Ne dediğinizi yanlış anlamadıkça, hiçbir "@ Lazy" fasulye kullanıcısına gitmiyor. [@Lazy Javadoc] 'dan (http://docs.spring.io/spring/docs /current/javadoc-api/org/springframework/context/annotation/Lazy.html): _May, @Component ile doğrudan veya dolaylı olarak eklenmiş herhangi bir sınıfta veya @Bean ile açıklamalı yöntemlerde kullanılabilir ....Varsa ve true olarak ayarlanırsa, @Bean veya @Component başka bir fasulye tarafından referans alınana kadar veya BeanFactory._ –

+0

@ AshleyFrieze'den açıkça alınana kadar başlatılmayacaktır, Spring 4'te, Biju'nun yanıtına göre aslında haklısınız demektir. teşekkürler :) –

cevap

29

Size bileşeni @Lazy yoksa, o zaman hevesle bir fasulye olarak oluşturulur olmasıdır. Bunun içinde @Autowired olduğu noktada yanı sıra bileşende @Lazy ek açıklaması zorunda ve senin @Autowired üzerinde bir @Lazy yoksa tekrar hevesle yaratılır ve fasulye içine enjekte edilir. Bu yüzden aşağıdakileri deneyin ve aşağıdakileri yapın:

@Component 
public final class WebDriverFactory { 
    @Autowired @Lazy 
    private CloseableChromeWebDriver chromeWebDriver; 
    @Autowired @Lazy 
    private CloseableFirefoxWebDriver firefoxWebDriver; 
+0

Burada geçen gece hakkında okuduğum gibi Spring 4'e ihtiyaç duyduğumdan eminim: http://zezutom.blogspot.com.au/2014/01/spring-series-part-4-lazy-on- injection.html. İlkbahar 3 atm kullanıyoruz, ancak aynı sayfa Sağlayıcı ile aynı etkiye nasıl ulaşılacağını açıklıyor gibi görünüyor. Bunu denemedim çünkü açıkçası henüz anlamadım. –

+0

Tamam, bunu test ettim .. İlkbahar 3 ile @Outowired @ Lazy' kullanamıyorum, ama Spring 4 ile yapabilirim - ve mükemmel çalışıyor. Ayrıca javax.inject.Inject' ve javax.inject.Provider’ın [Tom's Blog] olarak nasıl kullanılacağını öğrenmek için zaman harcadım (http://zezutom.blogspot.com.au/2014/01/spring- series-part-4-tembel-on-injection.html), ama çok fazladan ekstra kod alır çünkü her bir web sürücüsü için bir 'Sağlayıcı' tipi yazmak zorunda kalacağım çünkü her biri farklı sınıflar. –

+1

Sonuç olarak, İlkbahar 4'e geçebilirsem, @Outowired @ Lazy' tam olarak istediğimi yapar. İlkbahar 3 ile kalmam gerekiyorsa, 'appContext.getBean (..)' özelliğini bir uzlaşma olarak kullanmaya devam edeceğim için mutluyum. Öyleyse teşekkürler @Biju! –

İlgili konular