Пользовательский слушатель в Java - PullRequest
8 голосов
/ 02 июля 2010

В моем веб-приложении во время некоторых изменений объекта мне нужно отправить сообщение об изменениях, произошедших в объекте.Мой вопрос, как написать для этого слушателя.Пожалуйста, дайте мне статью об этом.Спасибо

Ответы [ 4 ]

22 голосов
/ 02 июля 2010

Типичная реализация может быть такой: ваш объект является наблюдаемым.Таким образом, каждый раз, когда изменяется одно из (наблюдаемых) значений, происходит событие, и все зарегистрированные слушатели получают уведомление.Один из таких слушателей теперь будет предназначен для получения уведомления, создания и отправки EMail (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);
}

И EMailer:

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
  }

}

РЕДАКТИРОВАТЬ Исправлена ​​ужасная ошибка вметод установки - теперь событие вызывается после свойство было установлено.И наоборот, с побочным эффектом, что если слушатель прочитал измененное свойство, он все еще видел старое, неизменное значение ...

6 голосов
/ 02 июля 2010

Если вы просто хотите узнать о свойствах изменяемого объекта, я бы рекомендовал использовать PropertyChangeListener.Таким образом, вы можете использовать служебный класс PropertyChangeSupport для управления экземплярами слушателя и запусками событий.Вы также избегаете изобретать велосипед.

Для более индивидуального запуска событий я бы порекомендовал определить собственный интерфейс слушателя.

Пример класса

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);
3 голосов
/ 16 декабря 2014

Вы должны использовать Шаблон проектирования наблюдателя .В этом шаблоне используются следующие классы:

Вот пример.

Наблюдатель:

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(...);
}
1 голос
/ 02 июля 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...