Java 通过注释实现@Autowired @Lazy @Components 的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26504224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to achieve @Autowired @Lazy @Components via annotations?
提问by Robert Mark Bram
Is there a way to have @Lazy
loading @Component
s that are still @Autowired
in a factory via annotations? The problem I found is that by autowiring my lazy components in the factory, they will all be instantiated immediately once the factory is loaded, negating the lazy annotation.
有没有办法通过注释让仍在工厂中的@Lazy
loading @Component
s @Autowired
?我发现的问题是,通过在工厂中自动装配我的惰性组件,一旦加载工厂,它们都会立即实例化,从而否定惰性注释。
I have defined several lazy beans such as
我已经定义了几个懒豆,比如
@Component
@Lazy
public final class CloseableChromeWebDriver
extends ChromeDriver
implements DisposableBean {
...
}
@Component
@Lazy
public final class CloseableFirefoxWebDriver
extends FirefoxDriver
implements DisposableBean {
...
}
It is important that they be lazy because
他们懒惰很重要,因为
- Whenever one of them is created, the browser window pops up.
- my data driven tests may or may not require any one or all of them i.e. one run may be all Firefox, or may require Firefox and Chrome.
- this is more important because in fact I have six such beans - Firefox, Chrome, IE, Remote Firefox, Remote Chrome, Remote IE.
- So, if my tests only use one of them, then I only want that one browser to show, not all them.
- 每当创建其中之一时,就会弹出浏览器窗口。
- 我的数据驱动测试可能需要也可能不需要其中任何一项或全部,即一次运行可能全是 Firefox,或者可能需要 Firefox 和 Chrome。
- 这更重要,因为事实上我有六个这样的 bean - Firefox、Chrome、IE、Remote Firefox、Remote Chrome、Remote IE。
- 所以,如果我的测试只使用其中之一,那么我只希望显示那个浏览器,而不是全部。
I have a Factory for getting the requested browser, but my first attempt at this failed because whenever any class used the factory, all of the autowired beans were being instantiated straight away, irrespective of whether they were actually requested. I understand this is because once the class is instantiated, it must instantiate all of the instance variables belonging to it.
我有一个用于获取请求的浏览器的工厂,但我第一次尝试失败,因为每当任何类使用该工厂时,所有自动装配的 bean 都会被立即实例化,而不管它们是否被实际请求。我理解这是因为一旦类被实例化,它必须实例化属于它的所有实例变量。
@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.
}
}
So here is my second approach which is to ensure lazy loading by requesting the bean through the application context:
所以这是我的第二种方法,它通过应用程序上下文请求 bean 来确保延迟加载:
@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;
}
}
This approach achieves my goal, but I feel it really negates the usefulness of using annotations. Is there a purely annotation based way to achieve this?
这种方法实现了我的目标,但我觉得它确实否定了使用注释的用处。是否有一种纯粹基于注释的方法来实现这一目标?
- JDK 6
- Spring 3.2.6.RELEASE
- No xml, just annotations.
- JDK 6
- 春季 3.2.6.RELEASE
- 没有xml,只有注释。
采纳答案by Biju Kunjummen
You have to have @Lazy
annotation on your component as well at the point where it is @Autowired
in. This is because if you don't have @Lazy
on your component, then it is eagerly created as a bean, and if you have don't have an @Lazy
on your @Autowired
then again it is eagerly created and injected into the bean. So try the following and it should just work:
你必须有@Lazy
注释你的组件上,以及在它是点@Autowired
英寸,这是因为如果你没有@Lazy
你的组件上,则急切地作为一个bean创建的,如果你有没有一个@Lazy
对你@Autowired
随后又热切地创建和注入豆。因此,请尝试以下操作,它应该可以正常工作:
@Component
public final class WebDriverFactory {
@Autowired @Lazy
private CloseableChromeWebDriver chromeWebDriver;
@Autowired @Lazy
private CloseableFirefoxWebDriver firefoxWebDriver;