请教一下关于Java中观察者模式的运用,实际场景如下(因为项目是使用Maven管理,所以单独又分了很多个小的Java Project):
如:A项目中:
@Service
public class ConfigServiceImpl extends ServiceImplBase {
// 该方法会通过一定时器定时查询并返回当前服务状态,即ServiceStatusBean
public ServiceStatusBean registerService(ServiceConfigBean config) throws TException {
//注册服务配置
ServiceStatusBean serviceStatusBean = serviceConfigHander.registerConfig(config);
return serviceStatusBean;
}
}
B项目中:
@Service
public class TimeStampServiceImpl extends ServiceImplBase{
// 此处待实现
}
目前想在B项目(标红处"此处待实现"注释那里)里根据观察者模式原理,在A项目中的服务状态改变的时候,这里也能及时
收到通知。不知道该如何更改。。。
PS:目前的想法是 把A作为主题,B作为观察者,当主题变化的时候即时通知每个观察者(当然目前这里只有B项目)。
------解决方案--------------------
大致代码如下,实际应用请自己修改。
public interface MyChangeListener extends java.beans.PropertyChangeListener{
}
@Service
public class ConfigServiceImpl extends ServiceImplBase {
// 该方法会通过一定时器定时查询并返回当前服务状态,即ServiceStatusBean
public ServiceStatusBean registerService(ServiceConfigBean config) throws TException {
//注册服务配置
ServiceStatusBean serviceStatusBean = serviceConfigHander.registerConfig(config);
return serviceStatusBean;
}
public void doSomeService(){
//Do something
//Trigger Event
support.firePropertyChange("", 1, 2);
}
private java.beans.PropertyChangeSupport support;
@PostContruct
public void init(ApplicationContext context){
support = new java.beans.PropertyChangeSupport();
Map<String, MyChangeListener> beans = context.getBeansOfType(MyChangeListener.class);
for(Map.Entry<String, MyChangeListener> entry : beans.entrySet()){
support.addPropertyChangeListener(entry.getValue());
}
}
}
@Service
public class TimeStampServiceImpl extends ServiceImplBase implements MyChangeListener{
public void propertyChange(PropertyChangeEvent evt){
Object newVal = evt.getNewValue(), oldValue = evt.getOldValue();
String propertyName = evt.getPropertyName();
//TODO something for this event.
}
}
------解决方案--------------------
刚看到你是2个工程的项目要相互通信。
比较优雅的方案有2个。
第一种:B项目对外暴露一个webservice,A项目属性变动时访问此WebService即可通知。
第二种:增加一个JMS服务容器,A项目建立一个订阅者的消息队列。B项目去监听A项目的消息队列。A有情况时发送消息到队列B即可收到,并做相应处理。注:此方法可以多个工程同时监听A的消息队列,也就是说谁关心A的变动谁就去监听A的消息队列。
个人比较倾向于第二种方法。
------解决方案--------------------
A项目 添加针对状态改变的监听器对象
B项目 实现监听器的操作
示例代码:
/**
* 状态变化监听器,当状态变化时出发监听器的方法
*/
public interface StatusChangeListener{
/**
* 当前后两种状态发生变化时,触发该方法的调用
* @param lastStatus 上一次的状态
* @param currentStatus 当前状态
*/
void onStatusChanged(ServiceStatusBean lastStatus, ServiceStatusBean currentStatus);
}
@Service
public class ConfigServiceImpl extends ServiceImplBase {
private ServiceStatusBean lastStatus;
private List<StatusChangeListener> listeners = new ArrayList<StatusChangeListener>();
// 该方法会通过一定时器定时查询并返回当前服务状态,即ServiceStatusBean
public ServiceStatusBean registerService(ServiceConfigBean config) throws TException {