lunes, octubre 17, 2011

Una terra promessa Un mondo diverso Dove crescere i nostri pensieri Noi non ci fermeremo Non ci stancheremo di cercare Il nostro camino (Terra Promessa - Eros Ramazzotti)


INTRODUCTION

The essence of the Observer Pattern is to "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically." GoF. Observer pattern is a subset of publish/subscribe pattern which allows a number of observer objects to see an event. 

This pattern can be used in different situations, but in summary we can say that Observer pattern can be applied when an object should be able to notify messages to other objects, and you don't want these objects  being tightly coupled. In my case I have used this pattern when an asynchronous event should be notified to one or more graphical component.

This pattern can be implemented using an adhoc solution or using java.util.Observer/Observable classes. But my projects are always developed with Spring whether they are web or desktop applications. So in current post I will explain how I implement Observer pattern with Spring.

HANDS ON

Event handling in Spring ApplicationContext is provided through ApplicationEvent class and ApplicationListener interface. If a bean that implements ApplicationListener interface is deployed into the context, every time an ApplicationEvent is published to container, ApplicationListener receives it.

Spring comes with built-in events, like ContextStartedEvent, ContextStoppedEvent, but you can also create your own custom events.

For developing your own events, three classes are required, observer role, observable role and the event. Observers are those who receive events and must implement ApplicationListener class. Observable classes are responsible of publishing events and must implement ApplicationEventPublisherAware. Finally event class has to extend ApplicationEvent.

CODING

What I am going to implement is wikipedia example of Observer pattern (http://en.wikipedia.org/wiki/Observer_pattern#Example) but using Spring Events instead of Observer/Observable Java classes. The example is a basic publish/subscribe example where one String message is sent from one module to another one.

Let's create MessageEvent. This event contains a String that represents the message we want to send. It is a simple class that extends from ApplicationEvent.


Next class is the Observable class. This class must implements ApplicationEventPublisherAware. This interface defines a setter method with ApplicationEventPublisher as parameter. This parameter is used for publishing events.

In current implementation see that also implements Runnable interface so user can create from console input, asynchronous messages. Most important line is 26 where an event is created and published.


The Observer class is even simpler. Implements ApplicationListener interface. Method onApplicationEvent is called when an event is published. See that it is a generic interface, so no cast is required. This differs from java.util.Observer class.


In application context file, you register both ApplicationListener and ApplicationEventPublisherAware beans.

And finally a main class to test the system. A thread is created to execute multiple asynchronous events. 


So start the program and write something to console. You will see something like:

hello
Thread-0
Thread-0
MessageEvent [message=hello]

I have entered "hello" message and thread name of event publisher is printed. Then event is sent and handler thread name is printed too. Finally the received event is shown. There is one thing that should call your attention. Both sender (Observable) and receiver (Observer) are executed in same thread; by default event listeners receive events synchronously. This means that publishEvent() method, blocks until all listeners have finished processing the event. This approach has many advantages (for example reusing transaction contexts, ...), but in some cases you will prefer that each event is executed in new thread, Spring also supports this strategy.

In Spring, class responsible of managing events is SimpleApplicationEventMulticaster. This class multicasts all events to all registered listeners, leaving it up to the listeners to ignore events that they are not interested in. Default behaviour is that all listeners are invoked in calling thread. 

Now I am going to explain how Spring Event Architecture is initialized and how you can modify. By default when ApplicationContext is started up, it calls initApplicationEventMulticaster method. This method verify if exists a bean with id applicationEventMulticaster of type ApplicationEventMulticaster. If it is the case defined ApplicationEventMulticaster is used, if not a new SimpleApplicationEventMulticaster with default configuration is created.

SimpleApplicationEventMulticaster has a setTaskExecutor which can be used for specifying which java.util.concurrent.Executor will execute events. So if you want that each event is executed in a different thread, a good approach would be using a ThreadPoolExecutor. As explained in last paragraph, now we must explicitly define SimpleApplicationEventMulticaster instead of using default ones. Let's implement:


First of all SimpleApplicationEventMulticaster must be defined as a bean with id applicationEventMulticaster. Then task pool is set, and we rerun our main class. And output will be:

hello
Thread-1
pool-1
MessageEvent [message=hello]

Note that now sender and receiver thread is different.

And of course you can create your own ApplicationEventMulticaster for more complex operations. You just have to implement ApplicationEventMulticaster and defining it with applicationEventMulticaster bean name, and events will be executed depending on your own strategy.

Hope that now your Spring desktop applications can take full advantage of Spring events for separating modules.


Music: http://www.youtube.com/watch?v=GfnkcKiocRw

4 comentarios:

Anónimo dijo...

How would this work in a JEE environment? Most appliction servers don't want you to spawn a new thread since you will be using the JEE context. App servers like WAS have their own thread pool and a factory for a runnable. So, does that mean that your solution is not appropriate for a JEE app?

Alex Soto dijo...

Hi, you can also use this approach in JEE environment, Spring container is responsible of managing pool of threads, of course you should take in consideration how many connections will you receive, and so you can tune pool of threads correctly.

Thank you so much for reading my blog.

chenlina dijo...

chenlina20160716
michael kors handbags
louis vuitton outlet stores
coach outlet
coach outlet
ghd hair straighteners
louis vuitton outlet
adidas nmd
toms shoes
true religion outlet
ray ban sunglasses discount
oakley sunglasses
louis vuitton bags
michael kors outlet
louis vuitton
hermes handbags
nike trainers men
ray ban sunglasses
nike free runs
pandora jewelry
cheap nfl jerseys
cheap air jordans
gucci handbags
louis vuitton handbags
burberry bags
louboutin shoes
michael kors outlet online sale
michael kors purses
adidas superstar
oakley sunglasses
beats by dr dre
gucci belts
coach factory outlet online
cheap oakley sunglasses
michael kors outlet
louis vuitton handbags
coach factory outlet
oakley canada
toms wedges
louis vuitton
coach outlet
as

Gege Dai dijo...

mulberry handbags
ralph lauren outlet
nba jerseys
coach outlet online
rolex outlet
ralph lauren outlet
fitflops sale clearance
swarovski jewelry
true religion jeans sale
tiffany and co
michael kors handbags
ray-ban sunglasses
cheap jordan shoes
coach outlet
cazal outlet
longchamp
michael kors handbags
mulberry handbags
abercrombie outlet
fitflops outlet
tiffany outlet
nike huarache
oakley sunglasses wholesale
ferragamo shoes
ray ban sunglasses
cheap nba jerseys
gucci outlet
cheap mlb jerseys
michael kors outlet
michael kors outlet
police sunglasses for men
michael kors handbags
michael kors outlet
michael kors outlet online
coach outlet
czq20160722

Donate If You Can and Find Post Useful