gpt4 book ai didi

java - Web 应用程序中的 Spring 应用程序上下文刷新

转载 作者:行者123 更新时间:2023-11-30 03:17:51 24 4
gpt4 key购买 nike

在我的应用程序中,在服务器启动期间,Spring bean DAO 类从数据库读取值并使用 spring jdbc 模板存储在 HashMap 中。

我需要在运行时重新加载一组特定的 bean,而无需重新启动应用程序服务器。

下面是我的代码片段。如果需要的话我可以发布更多内容

private void setMessageDetails() {
messageContentDetails= namedParameterJdbcTemplate.queryForObject(messageContentSql,nameParamMap, new MessageContentRowMapper());
}

MessageContentRowMapper.java maps the resultset values to valuesMap below

public class MessageContentDetails {
private Map<String, Map<String, String>> valuesMap= new HashMap<String, Map<String, String>>();
..setters/getters..
}

现在,如果任何数据库值发生变化,我需要重新初始化 MessageContentDetails.java 并使用新值更新 hashmap,并再次 Autowiring 该类的引用,无论它以前在应用程序启动期间 Autowiring /注入(inject)。

我的问题是

  1. 我可以使用 applicationContext.refresh() 方法刷新一个或一组几个 spring bean 吗?
  2. 是否有更好的方法来重新加载具有一些需要在运行时重新加载的静态值的 spring bean?
  3. 使用此方法可能对线程产生哪些影响。我的应用程序分布在 3 个不同的数据中心,具有多个 jvm。

任何指向我上述问题的链接都会非常有帮助。

我使用的是 JAVA 1.6 WebSphere Spring 3.1.0 版本,MessageContentDetails bean 是在 spring xml 中配置的 spring bean,没有注释。

最佳答案

我不确定这是否可以通过开箱即用的 Spring 来实现,通过一些技巧和多个上下文也许可以实现。默认情况下,Spring 将在刷新时销毁某些上下文中的所有单例。

但是,考虑到您的情况,在没有 Spring 参与的情况下实现此要求并不难。

您需要做的是在运行时更新静态 map ,仅此而已:)

通用解决方案:

1) 引入网络服务,让您可以提供新的更新值,

2)制作依赖于可更新bean观察者的bean并提供 block 释放机制,

3)

  • 通过反射或多态性编写通用映射,使您可以更新任何 bean 的静态值

  • 编写 Web 服务负载和目标 Bean 状态之间的特定映射。

让我们从 1 开始:

@Controller
public class BeanUpdateController {

@Autowired
private UpdateService updateService;


@RequestMapping(value = "/updateState", method = RequestMethod.POST)
@ResponseBody
public UpdateResponse handleUpdateRequest(@Valid @RequestBody someXMLYouDefine updateRequest) {

return updateService.execute(voucher);
}

请注意,您还可以使用 RequestMethod.GET 和 URL 参数。

但是,您的想法是,以某种可解析的格式传输您希望更新的 Bean 的名称、字段名称和适当的值。

让我们进入3:

@Component
public class BeanLocator implements ApplicationContextAware {

private static ApplicationContext context;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}

public Object getBean(String beanName) {

return context.getBean(beanName);

}

protected ApplicationContext getContext() {

return context;
}

此服务允许您按名称查找 Bean,该名称包含在 Web 服务的有效负载中。

一旦您获得了 bean,您就有几个选择:

1) 让“可更新”Bean 实现一些接口(interface),例如Updatable 并向它们传递它们将自行更新的字段名称和值。

2)使用反射,也许像这样:

对于有效负载中的每个字段名称:

Field field = acquiredBean.getClass().getDeclaredField("fieldNameFromThePayload");

如果它是一个原语,你可以这样做:

field.setAccessible(true);
field.set(acquiredBean,"valueFromPayload")

如果它是一个集合或映射,并且如果您使用 XSD 表示此结构,则可以直接将列表从生成的类映射到目标 bean。当然,您也可以迭代并手动执行此操作。

实现选项 3 的最简单但最不灵活的方法是简单地将值作为 GET 请求上的 URL 参数传递,并让服务获取对 Bean 映射的引用,然后更新该映射。

现在回到第二步,如果这对业务不重要,您可以跳过该步骤。

每个可能依赖于“可更新”bean 的 bean 都应该实现 Observer 接口(interface)。当更新请求到来时,他们通过策略模式切换实现,以在正在进行更新时对所有传入请求进行排队。一旦 bean 更新,它应该发送确认。这将触发监听服务的另一个通知,该通知将解锁排队的请求并继续处理。

Web 服务更新请求应广播到所有具有可更新 bean 的节点。

关于java - Web 应用程序中的 Spring 应用程序上下文刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32127161/

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