Lecture 10

Java Beans

The topic which we will be discussing today is very important from the software engineering perspective. It illustrates the next step in the evolution of philosophy of software development. Today we will talk about Java beans. Java beans is an example of Component based model. The idea of the component based model is quite simple. An engineer develops a set of components with customizable behavior which then can be reused by others. We can find examples of such approaches in may contemporary GUI builders. For example in Visual Basic we have tons of such components, which can be changed dynamically and interact with each other. These components should be flexible and general enough to be useful in many applications. Components are self-contained, yet they can be controlled dynamically, can interact with other components and can be assembled to be used in applications. These components have well defined properties and behavior. Usually, these components have visual editors which allow programmers to customize their properties.

Typical component based frameworks allow components to be found and plugged-in dynamically. Once component is registered it is known and is available. To facilitate the interaction among components and also with the environment, such components are capable of dispatching and handling events. Components are capable of storing their state (Serialization) and then reconstructing themselves back.

So Java beans is component based architecture created by Sun Microsystems. Unlike other such frameworks (ActiveX), the design of Java beans is simple, elegant and beautiful.

What is the difference between Component and, say class in Java? Hopefully by the end of this lecture you will see all the differences. One major difference is that Component is essentially a class which is written in a particular way. It is written in such a way that it is possible to recognize it as Java bean. Nevertheless, Java beans don't change Java language at all. Beans are written in Java, so programmers don't need to learn any new language to create beans. All they need to do is to familiarize themselves with bean architecture and package java.beans (since JDK 1.1). Okay, so here comes our first bean!

How is this a bean?! Very simple. The minimum thing which is required for the class to be a bean in Java is that it would have GET and SET methods for customizable properties, which are named in the consistent way. For example, the bean above offers accessor and modifier for the same property called age. The notation, as you've noticed is like this

To outside this bean offers property Age, which is both accessible and modifiable.

We have to note that if property is of type boolean, then get method can have the following form:

public boolean is<PropertyName>();

Another thing that we need to point out is that the name of the variable which is storing the actual value NEED NOT to match exactly the names which are part of the accessor and modifier methods

This is just as valid. Of course, for consistency and readability sake, it would be better to name them with the same name. Okay, so we see how to access and set these types of properties. Additionally, Java beans may have Indexed properties. Naturally, indexed properties represent a property which has series of values. Lets look at the following example:

The property genes is Indexed in the above been. As you can see there is a way to set and get all values at once, as well as access and set each separately. The general form of the above looks like this

So you get the idea.

What about notifying other parts of the application when bean property changes? Java beans come with rich supports for such notifications. The properties of Java beans are divided into Bound and Constrained.

Bound Properties

These are the properties which an external object sets on the bean. The changes in these properties cause bean to notify all the listeners which listen for all bean properties or this one in particular. The way beans notify its subscribers is similar to the events fired in AWT.

Here is what PropertyChangeEvent from java.beans looks like:

Subscribers register to receive these events via very simple interface

public void addPropertyChangeListener( PropertyChangeListener listener );
public void removePropertyChangeListener( PropertyChangeListener listener );

Okay, so what happens is this. Some object registers to receive notification for property changes from a bean, by calling addPropertyChangeListener. The PropertyChangeListener interface consists of only one method:

public void propertyChange( PropertyChangeEvent ev );

When change occurs beans loops through its subscribers and calls this method. Thus by using simple observer/observable pattern, bean notifies its listeners. But we are sick and tired of reimplementing the vector of listeners over and over again. Is it possible to ease our lives somehow? The answer is found in java.beans.PropertyChangeSupport and the answer is 'Yes!'.

The beans package offers a class whose will take care of most of the listener handling for any bean:

Instead of maintaining the list of subscribers and notifying them, beans simply instantiates PropertyChangeSupport object and forwards all the calls to it. This is, by the way, a standard design pattern technique. Notice the following important things about this design. Common functionality is captured and factored out into a class, which then can be used by others. Notice that important role is played here by the fact that only ONE TYPE of event is delivered to subscribers, namely PropertyChangeEvent. Recall the Parser - TagExtractor listener interface, where we had tagStart, tagEnd, tagAttribute methods. Instead, following standard Java event handling approach we could have created an event class, call it TagExtractorEvent and have integer field for identifying if it was tag start, tag end or an attribute. Okay, back to beans.

Lets take a look at the example which summarizes the ideas above:

As you would expect when we call setAge in main, the changes get propagated all the way to propertyChange call. This is the typical way that we would handle BOUND NON SPECIFIC properties in beans. Notice that in the current setup if we have several listeners which are interested, say, in different properties of a particular bean, there is no way that we can send them changes only in the ones which they are interested. However, optionally bean can have the following functionality:

public void add<PropertyName>Listener( PropertyChangeListener listener );
public void remove<PropertyName>Listener( PropertyChangeListener listener );

This functionality is very useful. It can be trivially implemented via hash table of properly names to property change supports. Thus, in the Entity bean example, users of the bean would be able to say:

public void addAgeListener( PropertyChangeListener listener );
public void removeAgeListener( PropertyChangeListener listener );

One very important not about bound properties is that listeners get notified only AFTER any changes occur in the bean. The bean implementor is required to first set the new value and then notify the listeners.

Constrained properties

What if we desire different type of behavior. What if we want to be able to have observers which can prohibit or approve the change? This functionality is build into beans via Constrained properties. When a change in such property occurs, the subscribers are notified first and they may prevent the change from happening by throwing PropertyVetoException. If all of the listeners approves then the change take place. Lets take a look at the api, which is very similar to the bind properties:

First of al, the set method now can throw PropertyVetoException:

public void set<PropertyName>( TYPE arg ) throws PropertyVetoException;

This is how you would add the vetoable listener:

public void addVetoabaleChangeListener( VetoableChangeListener listener );
public void removeVetoableChangeListener( VetoableListener listener );

The same PropertyChangeEvent is fired, and listeners method veatobleChange, which is the only method in VetoableChangeListener interface gets called. But now the listener may throw

an exception. Lets look at the implementation of the Vetoable property

This produces the following output

Lets take a close look at the output. Notice that after we throw the exception, we received new update with the old value! This should take us a little while to reason through. Say you have a bean with 10 listeners and fourth listener vetoes the change we need to loop through the listeners and notify them that we revert to the old value! Sure enough if we look in VetoablePropertySupport you will see exactly that

Okay, lets summarize that we learned about bean properties in the diagram

We already touched on the topic of Java serialization. As you remember serialization is essentially concerned with taking a snapshot of an object. This can be useful for sending objects over the socket or storing them persistently. Lets take a look at Java serialization and see how it is useful from the Java beans perspective. In Java serialization is a freebie. This is not a joke, essentially to serialize an object you only have to implement Serializable interface. If you look at Sun's code you will see that this interface is empty! it is really a dummy which signals compiler to generate serialization code. The trick is that support for serialization is ingrained into all Java class starting from, of course, Object.

You have to use ObjectInputStream and ObjectOutputStream to serialize your objects.

Now if you look at the file SerializationDemo.ob in WordPad, you will see something like this (I added the new lines myself)

We simply call methods writeObject and readObject on the ObjectOutputStream and ObjectInputStream respectively and we don't have to worry about it! This is way too cool. You can't have anything this easy in C++. What if you don't want a field to be serialized? Simple just mark it transient like this

The output looks like this

Serialization becomes really handy for beans. We can store a snapshot of a bean using serialization mechanism we just saw. So now imagine that we customized a bean, we choose desirable values for properties and added listeners. Now we serialize it - the state is remembered. If you look at java.beans.Beans class there is a static method called instantiate.

This method helps us to load beans meaningfully. If there is already a serialized version the given bean, it gets loaded and bean constructor is NOT even called. You get a handle on the object which was just read using serialization. On the other hand, if it is not there then instantiate acts like new, it calls Class.forName and then creates an instance of this class. Note that beans must have no-arg constructors in order for this to work.

Next time we will look and introspection and bean editors.