Search code examples
javaspring-bootobserver-pattern

How to register a Observer using Spring Boot?


I want to implement the GoF Observer Design Pattern using Spring Boot without Spring Events.
Code sample:

    @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); //??
    

Solution

  • Are the java.util classes a good implementation for that pattern ?

    The GoF pattern and the java implementation of it are a bit dated and have some issues.
    It really depends on the problem you are trying to solve, but it might be suitable if your application doesn’t make massive use of events and you don’t want to introduce something like spring events or RxJava.

    How can I register the observer with the observable , and still able to use Spring Depedency Injection? Where I can call myObserver.accept(myObservable); ?

    See the below example of how you can define an Observable some observers, wire them up and finally send some events to them.

    @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);
            }
        }
    }