Java中的用户定义侦听器

Java中的用户定义侦听器,java,Java,在我的web应用程序中,在对对象进行某些更改期间,我需要发送一封关于对象中发生的更改的邮件。 我的问题是如何为此编写侦听器。 请给我一些关于这个的文章。 感谢使用Observer设计模式。 一个典型的实现可能是这样的:您的对象是可观察的。因此,每当一个(观察到的)值发生变化时,就会触发一个事件并通知所有注册的侦听器。其中一个监听器现在将被设计为接收通知并创建和发送电子邮件(Java Mail API) 让我们取一个样本bean,使其可观察: public class Bean implement

在我的web应用程序中,在对对象进行某些更改期间,我需要发送一封关于对象中发生的更改的邮件。 我的问题是如何为此编写侦听器。 请给我一些关于这个的文章。
感谢使用Observer设计模式。
一个典型的实现可能是这样的:您的对象是可观察的。因此,每当一个(观察到的)值发生变化时,就会触发一个事件并通知所有注册的侦听器。其中一个监听器现在将被设计为接收通知并创建和发送电子邮件(Java Mail API)

让我们取一个样本bean,使其可观察:

public class Bean implements Observable{

  // code to maintain listeners
  private List<Listener> listeners = new ArrayList<Listener>();
  public void add(Listener listener) {listeners.add(listener);}
  public void remove(Listener listener) {listeners.remove(listener);}

  // a sample field
  private int field;
  public int getField() {return field;}
  public int setField(int value) {
    field = value;
    fire("field");        
  }

  // notification code
  private void fire(String attribute) {
    for (Listener listener:listeners) {
      fieldChanged(this, attribute);
    }
  }
}
可观察界面:

public interface Listener {
  public void fieldChanged(Object source, String attrbute);
}
public interface Observable {
  public void add(Listener listener);
  public void remove(Listener listener);
}
电子邮件发送人:

public class Sender implements Listener {

  public void register(Observable observable) {observable.add(this);}
  public void unregister(Observable observable) {observable.remove(this);}

  public void fieldChanged(Object source, String attribute) {
    sendEmail(source, attribute); // this has to be implemented
  }

}
编辑
更正了setter方法中的一个严重错误-现在,在设置属性后触发事件。另一方面,如果听者阅读了更改的属性,他仍然看到了旧的、未更改的值,则会产生副作用

如果您只是想了解被修改对象的属性,我建议您使用。这样,您就可以使用实用程序类来管理侦听器实例和事件的触发。你还可以避免重新发明轮子

对于更多定制的事件触发,我建议您定义自己的侦听器接口

示例类

public class MyBean {
  private final PropertyChangeSupport support;

  private int i;
  private boolean b;

  public MyBean() {
    this.support = new PropertyChangeSupport(this);
  }

  // Accessors and Mutators.  Mutating a property causes a PropertyChangeEvent
  // to be fired.
  public int getI() { return i; }

  public void setI(int i) {
    int oldI = this.i;
    this.i = i;
    support.firePropertyChange("i", oldI, this.i);
  }

  public boolean getB() { return b; }

  public void setB(boolean b) {
    boolean oldB = this.b;
    this.b = b;
    support.firePropertyChange("b", oldB, this.b);
  }

  // Wrapper methods that simply delegate listener management to
  // the underlying PropertyChangeSupport class.
  public void addPropertyChangeListener(PropertyChangeListener l) {
    support.addPropertyChangeListener(l);
  }

  public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
    // You would typically call this method rather than addPropertyChangeListener(PropertyChangeListener)
    // in order to register your listener with a specific property.
    // This then avoids the need for large if-then statements within your listener
    // implementation in order to check which property has changed.

    if (!"i".equals(propertyName) && !"b".equals(propertyName)) {
      throw new IllegalArgumentException("Invalid property name: " + propertyName);
    }

    support.addPropertyChangeListener(propertyName, l);
  }

  public void removePropertyChangeListener(PropertyChangeListener l) {
    support.removePropertyChangeListener(l);
  }

  public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
    support.removePropertyChangeListener(propertyName, l);
  }
}
示例用法

// Create a new instance of our observable MyBean class.
MyBean bean = new MyBean();

// Create a PropertyChangeListener specifically for listening to property "b".
PropertyChangeListener listener = new PropertyChangeListener() {
  public void propertyChange(PropertyChangeEvent evt) {
    assert "b".equals(evt.getPropertyName());
    boolean oldB = (Boolean) evt.getOldValue();
    boolean newB = (Boolean) evt.getNewValue();

    System.err.println(String.format("Property b updated: %b -> %b, oldB, newB));
  }
}

// Register listener with specific property name.  It will only be called back
// if this property changes, *not* the "i" int property.
bean.addPropertyChangeListener("b", listener);

您应该使用。此模式使用以下类:

这里有一个例子

观察员:

public class EmailObserver implements Observer
{
    @Override
    public void update(Observable obj, Object arg)
    {
        if (obj instanceof YourObject)
        {
            // TODO Send the mail or whatever, you have access to the modified object through obj
            // In arg you can put some additional parameter, like the modified field
        }
    }
}
可观察物体:

public static class YourObject extends Observable
{
    public void setSomething(Object parameter)
    {
        // TODO some modification in YourObject

        setChanged(); // From Observable : the object has changed
        notifyObservers(parameter); // Notify the observer about the change
    }
}
主要课程包括:

public static void main(String[] args)
{
    // Create YourObject
    YourObject o = new YourObject();

    // create an observer
    EmailObserver emailObserver = new EmailObserver();

    // subscribe the observer to your object
    o.addObserver(emailObserver);

    // Now you can modify your object, changes will be notified by email
    o.setSomething(...);
}

尝试搜索“java中的自定义事件”可以修改objects类的源代码吗?根据法律,你能让那个类成为可观察的,还是我们需要一个单独的观察者来观察那个对象?兄弟,这是一个很好的问题,真的很有用+1我建议使用CopyOnWriteArrayList而不是ArrayList。否则,侦听器实现可能会在通知期间删除自身,从而导致ConcurrentModificationException。