如何在Spring Boot中注册一个观察者?

4

我想使用Spring Boot实现GoF观察者设计模式,而不使用Spring Events。
代码示例:

    @Component
    public class MyObservable extends java.util.Observable {
      void myObservableMethod(Object obj){
        notifyObservers(obj);
      }
    }

    @Component
    public class MyObserver implements java.util.Observer{  
    @Override
      public void update(java.util.Observable observable, Object obj) {
        System.out.println(obj.toString());
      }
    }
  1. Are the java.util classes a good implementation for that pattern ?
  2. How can I register the observer with the observable , and still able to use Spring Depedency Injection?
    Where I can call myObserver.accept(myObservable); ?

    @Autowired
    MyObservable myObservable;
    @Autowired
    MyObserver myObservable;
    
    myObserver.accept(myObservable); //??
    
1个回答

1
“java.util”类是该模式的一个很好的实现吗?GoF模式及其Java实现有些过时并存在一些问题。这真的取决于您要解决的问题,但如果您的应用程序不会大量使用事件,并且您不想引入诸如Spring事件或RxJava之类的东西,则可能是合适的。
“我如何向可观察对象注册观察者,同时仍然能够使用Spring依赖注入?在哪里可以调用myObserver.accept(myObservable)?”请参见以下示例,了解如何定义可观察对象、一些观察者,将它们连接起来并最终向它们发送一些事件。
@SpringBootApplication
public class ObserverApplication {

    public static void main(String[] args) {
        try(ConfigurableApplicationContext ctx = SpringApplication.run(ObserverApplication.class, args)){
            Observable observable = ctx.getBean(Observable.class);
            observable.notifyObservers("Hello");
        }
    }

    @Bean
    public Observable myObservable(){
        return new MyObservable();
    }

    @Bean
    MyObserver observer1(){
        return new MyObserver(1);
    }

    @Bean
    MyObserver observer2(){
        return new MyObserver(2);
    }

    @Autowired
    public void configureObservers(Observable myObservable, MyObserver observer1, MyObserver observer2){
        myObservable.addObserver(observer1);
        myObservable.addObserver(observer2);
    }

    static class MyObserver implements Observer {

        int id;

        public MyObserver(int id) {
            this.id = id;
        }

        @Override
        public void update(Observable o, Object arg) {
            System.out.println("Observer: " + id + ", Received object: " + arg);
        }
    }

    static class MyObservable extends Observable {
        @Override
        public void notifyObservers(Object arg){
            this.setChanged();
            super.notifyObservers(arg);
        }
    }
}

谢谢你的回答。但是configureObservers()在哪里被调用? 还有更好的实现方式吗? - Yuri S
如果一个方法被标注为 @Autowired 并且它所在的类是一个 bean,那么 Spring 将尝试在上下文初始化期间装配该方法,它将尝试查找匹配参数的 bean 并调用该方法。我已经给出了关于如何使用 java.util 实现观察者模式的最佳答案,如果你想要关于使用 Spring 事件或其他框架的建议,那么你可能需要提一个新问题。 - Magnus
谢谢你的解释,Magnus! - Yuri S
很遗憾,它没有起作用,在我的程序中,观察者没有被可观察对象调用。我想Spring构建了一个对象池并配置了configureObservers()注入的Observable的一个实例。是否有一种方法可以设置此池中的所有对象? - Yuri S
春天的Beans通常是单例的,如果您手动创建对象,则将是不同的实例。 我的示例中有一个observable和两个observers,但您可以适应任何固定数量的observables / observers。 如果您不知道将有多少个,即需要在运行时动态生成对象,则变得更加棘手,最好只需将spring排除在生命周期之外。 - Magnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接