gpt4 book ai didi

java - 如何(以及何时)初始化需要访问仅在运行时已知的其他 bean 的 Spring bean?

转载 作者:行者123 更新时间:2023-11-30 02:16:45 25 4
gpt4 key购买 nike

我有一个在 Java 5 上运行的 Spring Web 应用程序。这个 我的 applicationContext.xml 文件:

<bean id="child1" class="foo.ChildOne" />
<bean id="child2" class="foo.ChildTwo" />
<bean id="main" class="foo.Main">
<property name="childrenList">
<list value-type="foo.IChildren">
<ref bean="child1" />
<ref bean="child2" />
</list>
</property>
</bean>

ChildOneChildTwo 类都实现 IChildren 接口(interface)。在我的 Main 类中,我定义了一个 childrenList,其中填充了 child1child2 bean。 Easy, right?

但将来,可能不会有 child1,相反,我们可能会有一个基于另一个未知类的 child81。而且它仍然需要在不接触当前代码或 XML 文件的情况下工作,只能通过配置来实现。这个 child81 将在其自己的 applicationContext 文件(在 JAR 中)中定义,我们将在数据库字段中列出 bean 名称(child2、child81 等)。

我想这不是一个好的设计模式;最有可能的是,这是一个可怕的、可怕的、痛苦的、你最好趁还能跑的设计,这将在未来的几年里困扰着我。但我没有定义它,并且我无法更改它,所以请假设对于这个问题来说这是可以的。

我必须在运行时以某种方式检索它们,而不是使用 applicationContext.xml 自己注入(inject) bean。我也无法使用 Autowiring ,因为我不知道这些 bean 是什么类,我只知道它们的所有类都实现了 IChildren

所以我创建了我的主 bean 类 ApplicationContextAware 并添加了此方法:

public void loadChildren() {
if (childrenList == null) {
childrenList = new LinkedList<IChildren>();
for (String name : theListOfBeanNames) {
childrenList.add((IChildren) context.getBean(name));
}
}
}

一切正常;每个 bean 都在其自己的 applicationContext 中定义,然后我按名称检索它们。但是......我什么时候调用loadChildren()?到目前为止,我正在每个方法的第一行中执行此操作。由于存在空检查,因此它只会初始化列表一次。但肯定有一种更简单/更干净/更好的方法来做到这一点?

我认为我不能在 applicationContext 中使用 init-method="loadChildren" 属性,因为如果我的主 bean 正在运行,它就会失败在所有 child 之前加载...并且我无法控制加载顺序。或者我可以吗?

这是来 self 的 web.xml 文件:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-context/applicationContext-*.xml
,classpath*:WEB-INF/application-context/applicationContext-children.xml
</param-value>
</context-param>

(我们使用“classpath* notation ”从 JAR 中加载每个 applicationContext-children.xml 文件)。如果我颠倒顺序并将子 XML 放在主要 XML 之前,是否可以确保它们按照特定顺序加载?不管我们使用什么版本的应用服务器?

我还看到了@PostConstruct annotation如果我可以将其添加到我的 loadChildren 方法中,这将很有用。但什么时候会被调用呢?我读到这是在注入(inject)完成之后,但是......仅适用于当前的 bean,对吧?它不能确保所有其他 bean 都已加载?

还有其他选择吗?

最佳答案

Spring 可以为你做到这一点:

@Component
public class MyComponent {
@Autowired
private final List<IChildren> children;

...
}

除了实现 IChildren 之外,这将 Autowiring 所有内容。

关于java - 如何(以及何时)初始化需要访问仅在运行时已知的其他 bean 的 Spring bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48149618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com