在我的应用程序中,在服务器启动期间,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并使用新值更新hashmap,并再次自动装配此类的引用,无论它在应用程序启动期间以前是否已自动装配/注入。
我的问题是
任何与上述问题相关的链接都会非常有用。
我使用的是JAVA 1.6 WebSphere Spring 3.1.0版本,而MessageContentDetails bean是一个在spring xml中配置而没有注释的spring bean。
答案 0 :(得分:2)
我不确定这是否可以通过Spring开箱即可实现,可能有一些技巧和多个上下文。默认情况下,Spring会在refresh
的某些上下文中销毁所有单身人士。
但是,考虑到您的情况,如果没有Spring的参与,实现这一要求并不困难。
您需要做的是在运行时更新静态Map,即:)
一般解决方案:
1)介绍Web服务,它允许您为更新提供新值,
2)创建依赖于可更新bean Observers
并提供块释放机制的bean,
3)
通过反射或多态来编写通用映射,它允许您更新任何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
和网址参数。
但是,您的想法是以一些可解析的格式传输要更新的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)让'updateable'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的所有节点。