Over a million developers have joined DZone.

Quick observable beans

DZone's Guide to

Quick observable beans

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

In recent years we have seen the rise of POJOs which differ from JavaBeans as they are not usualy made to be observable, in other words, they do not publish events whenever one of their properties changes value. Observable beans are usually linked to UI applications but they are surely useful in other scenarios, Groovy provides a quick way to create observable beans thanks to ObservableMap.

You are probably aware of the fact that Groovy blurred the distinction between beans and maps in term of syntax, and it also provides a base class for dynamic beans: Expando. One curious thing about expandos is that any property whose value is a Closure can be used as a method, another useful bit of information is that expandos accept a Map in their constructor, thus enabling dynamic observable beans in the following fashion

import java.beans.*

def events = []
// skip triggering an event if value is a Closure
def map = new ObservableMap( {!(it instanceof Closure)} )
// register a simple listener
map.addPropertyChangeListener({ evt ->
events << "${evt.propertyName}: ${evt.oldValue} -> ${evt.newValue}"
} as PropertyChangeListener)
// tie in the map and Expando
def bean = new Expando( map )
bean.name = 'Groovy'
bean.sayHello = { name -> "Hello $name" }

assert bean.name == 'Groovy'
assert bean.sayHello(bean.name) == 'Hello Groovy'
assert events.size() == 1
assert events[0] == "name: null -> Groovy"

bean.name = 'Duke'
assert events.size() == 2
assert events[1] == "name: Groovy -> Duke"

ObservableMap is a Map decorator, you can use it on its own or decorate a Treemap for a change.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}