java - how - spring injection constructor
¿La mejor forma de lograr @Autowired @Lazy @Components a través de anotaciones? (1)
¿Hay alguna manera de tener @Lazy
cargando @Component
s que todavía estén @Autowired
en una fábrica a través de anotaciones? El problema que encontré es que al autoautilizar mis componentes perezosos en la fábrica, todos se crearán una instancia inmediatamente una vez que se cargue la fábrica, negando la anotación perezosa.
He definido varios frijoles perezosos como
@Component
@Lazy
public final class CloseableChromeWebDriver
extends ChromeDriver
implements DisposableBean {
...
}
@Component
@Lazy
public final class CloseableFirefoxWebDriver
extends FirefoxDriver
implements DisposableBean {
...
}
Es importante que sean perezosos porque
- Cada vez que se crea uno de ellos, aparece la ventana del navegador.
- mis pruebas basadas en datos pueden o no requerir una o todas, es decir, una ejecución puede ser todo Firefox, o puede requerir Firefox y Chrome.
- esto es más importante porque, de hecho, tengo seis de esos beans: Firefox, Chrome, IE, Remote Firefox, Remote Chrome, Remote IE.
- Entonces, si mis pruebas solo usan una de ellas, entonces solo quiero que se muestre ese navegador, no todas.
Tengo una Fábrica para obtener el navegador solicitado, pero mi primer intento fracasó porque siempre que alguna clase usaba la fábrica, todos los frijoles con conexión automática se creaban de inmediato, independientemente de si realmente se habían solicitado. Entiendo que esto se debe a que una vez que se crea una instancia de la clase, debe crear una instancia de todas las variables de instancia que le pertenecen.
@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.
}
}
Así que aquí está mi segundo enfoque, que es asegurar la carga perezosa al solicitar el bean a través del contexto de la aplicación:
@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;
}
}
Este enfoque logra mi objetivo, pero siento que realmente niega la utilidad de usar anotaciones. ¿Hay una forma puramente basada en anotaciones para lograr esto?
- JDK 6
- Primavera 3.2.6.RELEASE
- No xml, solo anotaciones.
@Lazy
tener la anotación @Lazy
en su componente también en el punto donde está @Autowired
. Esto se debe a que si no tiene @Lazy
en su componente, entonces se crea con entusiasmo como un bean, y si tiene no tenga un @Lazy
en su @Autowired
, una vez más, se crea con entusiasmo y se inyecta en el frijol. Así que intente lo siguiente y debería funcionar:
@Component
public final class WebDriverFactory {
@Autowired @Lazy
private CloseableChromeWebDriver chromeWebDriver;
@Autowired @Lazy
private CloseableFirefoxWebDriver firefoxWebDriver;