繁体   English   中英

Web应用程序中的Spring Application Context Refresh

[英]Spring Application Context Refresh in webapplication

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

我需要在运行时重新加载一组特定的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并使用新值更新哈希图,并且还应再次自动装配该类的引用,而在应用程序启动期间,如果以前曾对其进行自动装配/注入过该类。

我的问题是

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

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

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

我不确定使用Spring开箱即用是否可以实现,可能有一些技巧和多个上下文。 默认情况下,Spring将在refresh在某些情况下销毁所有 Singleton。

但是,考虑到您的情况,没有Spring的参与就很难实现这一要求。

您需要做的就是在运行时更新静态地图,就是这样:)

通用解决方案:

1)引入网络服务,该服务可让您交付新值以进行更新,

2)制作依赖于可更新bean Observers bean,并提供块释放机制,

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)让“可更新” Beans实现某些接口,例如, Updatable ,并将它们将自行更新的字段名称和值传递给它们。

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

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

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

如果它是原始的,则可以执行以下操作:

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

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

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

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

每个可能依赖于“可更新” bean的bean都应实现Observer接口。 当有更新请求时,他们会通过策略模式将实现切换为在所有正在进行的更新期间将所有传入请求排队。 Bean更新后,它应该发送确认。 这将触发另一个侦听服务通知,该通知将取消阻塞排队的请求并继续处理。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM