What is a JavaBean exactly?

Viewed 725769

I understood, I think, that a "Bean" is a Java-class with properties and getters/setters.
As much as I understand, it is the equivalent of a C struct. Is that true?

Also, is there a real syntactic difference between a JavaBean and a regular class?
Is there any special definition or an Interface?

Basically, why is there a term for this?

Also what does the Serializable interface mean?

23 Answers

Just a little background/update on the bean concept. Many other answers actually have the what but not so much why of them.

They were invented early on in Java as part of building GUIs. They followed patterns that were easy for tools to pull apart letting them create a properties panel so you could edit the attributes of the Bean. In general, the Bean properties represented a control on the screen (Think x,y,width,height,text,..)

You can also think of it as a strongly typed data structure.

Over time these became useful for lots of tools that used the same type of access (For example, Hibernate to persist data structures to the database)

As the tools evolved, they moved more towards annotations and away from pulling apart the setter/getter names. Now most systems don't require beans, they can take any plain old Java object with annotated properties to tell them how to manipulate them.

Now I see beans as annotated property balls--they are really only useful for the annotations they carry.

Beans themselves are not a healthy pattern. They destroy encapsulation by their nature since they expose all their properties to external manipulation and as they are used there is a tendency (by no means a requirement) to create code to manipulate the bean externally instead of creating code inside the bean (violates "don't ask an object for its values, ask an object to do something for you"). Using annotated POJOs with minimal getters and no setters is much more OO restoring encapsulation and with the possibility of immutability.

By the way, as all this stuff was happening someone extended the concept to something called Enterprise Java Beans. These are... different. and they are complicated enough that many people felt they didn't understand the entire Bean concept and stopped using the term. This is, I think, why you generally hear beans referred to as POJOs (since every Java object is a POJO this is technically OK, but when you hear someone say POJO they are most often thinking about something that follows the bean pattern)

For a Java class to be usable as a Java bean, its method names need to be as per the JavaBeans guidelines (also called design patterns) for properties, methods, and events. The class needs to be a public class to be accessible to any beanbox tool or container. The container must be able to instantiate it; with the class as public, the container should be able to do so even if no explicit, public, zero-args constructor is provided. (A Java public class with no explicit constructor has a default public zero-args constructor.) So, minimally, a Java public class, even with a property as the sole member (of course, accompanying public getter and setter required) or a public method as the sole member, is a Java bean. The property can either be a read-only property (it has a getter method but no setter) or write-only property (has a setter method only). A Java public class with a public event listener registration method as the sole member is also a Java bean. The JavaBeans specification doesn’t require that if such a Java class has an explicit public constructor, it should be a zero-args one. If one could provide a file (with an extension, say, .ser) containing a serialized instance, a beanbox tool may be able to use that file to instantiate a prototype bean. Otherwise, the class would need a constructor, either explicit or default, that is public as well as zero-args.

Once the bean is instantiated, the JavaBeans API ( java.beans.*) can introspect it and call methods on it. If no class implementing the interface BeanInfo or extending a BeanInfo implementation,such as the SimpleBeanInfo class, is available, the introspection involves using reflection (implicit introspection) to study the methods supported by a target bean and then applying simple design patterns(the guidelines) to deduce from those methods what properties, events, and public methods are supported. If a class implementing the interface BeanInfo (for a bean Foo, it must be named FooBeanInfo) is available, the API bypasses implicit introspection and uses public methods (getPropertyDescriptor(), getMethodDescriptors(), getEventSetDescriptors() ) of this class to get the information. If a class extending SimpleBeanInfo is available, depending on which of the SimpleBeanInfo public methods (getPropertyDescriptor(), getMethodDescriptors(), getEventSetDescriptors() ) are overridden, it will use those overridden methods(s) to get information; for a method that is not overridden, it’ll default to the corresponding implicit introspection. A bean needs to be instantiated anyway, even if no implicit introspection is carried out on it. Thus, the requirement of a public zero-args constructor. But, of course, the Serializable or Externalizable interface isn’t necessary for it to be recognized. However, the JavaBeans specification says, ‘We’d also like it to be “trivial” for the common case of a tiny Bean that simply wants to have its internal state saved and doesn’t want to think about it.’ So, all beans must implement Serializable or Externalizable interface.

Overall, the JavaBeans specification isn’t hard and fast about what constitutes a bean. "Writing JavaBeans components is surprisingly easy. You don't need a special tool and you don't have to implement any interfaces. Writing beans is simply a matter of following certain coding conventions. All you have to do is make your class look like a bean — tools that use beans will be able to recognize and use your bean." Trivially, even the following class is a Java bean,

public class Trivial implements java.io.Serializable {}

The description so far is the Java SE version (JavaBeans). The beans, as described below, are the Java EE versions. These versions have been built on the underlying ideas as explained above. In particular, one main idea they consider is what if a bean constructor does have some parameters. These parameters could be either simple types, class/interface types or both. There should be a way to let the container know values that it can substitute for the parameters when instantiating the bean. The way to do so is that the programmer can configure (specify values) by say annotations or XML configuration files or a mix of both.

Spring Beans

Spring beans run in a Spring IoC container. The programmer can configure via XML configuration files, annotations or a mix of both.

In Spring, if a bean constructor has simple-type or class/interface type parameters, values can be assigned as strings (as the <value> attribute of a constructor argument element in the former case and as an <idref> element of a constructor argument in the latter case) in a type-safe manner. Making references to other Spring beans (called collaborators; via the <ref> element in a constructor argument element) is basically dependency injection and is also typesafe. Obviously, a dependency (collaborator bean) might have a constructor with injected parameters; those injected dependency(ies) might have a constructor with parameters and so on. This scenario should ultimately terminate at injected dependency(ies) that are prototype beans that the container can instantiate by constructing.

JSF Managed Beans

JSF managed beans run in a web container. They can be configured either with the @ManagedBean annotation or with an application configuration resource file managed-bean.xml. The JSF spec supports injection via resource injection (not typesafe) only. This injection is not fit for injection on constructors. In any case, the spec requires that a JSF managed bean must have a public zero-argument constructor. Further it says, “As of version 2.3 of this specification, use of the managed bean facility as specified in this section is strongly discouraged. A better and more cohesively integrated solution for solving the same problem is to use Contexts and Dependency Injection (CDI), as specified in JSR-365." In other words, CDI managed beans should be used, which do offer typesafe dependency injection on constructors akin to Spring beans. The CDI specification adopts the Managed Beans specification, which applies to all containers of the JEE platform, not just the web tier. Thus, the web container needs to implement the CDI specification.

Managed Beans

Here is an extract from the Managed Bean specification “ Managed Beans are container-managed objects with minimal requirements, otherwise known under the acronym “POJOs” (Plain Old Java Objects)…they can be seen as a Java EE platform-enhanced version of the JavaBeans component model found on the Java SE platform…It won’t be missed by the reader that Managed Beans have a precursor in the homonymous facility found in the JavaServer Faces (JSF) technology…Managed Beans as defined in this specification represent a generalization of those found in JSF; in particular, Managed Beans can be used anywhere in a Java EE application, not just in web modules. For example, in the basic component model, Managed Beans must provide a no-argument constructor, but a specification that builds on Managed Beans, such as CDI (JSR-299), can relax that requirement and allow Managed Beans to provide constructors with more complex signatures, as long as they follow some well-defined rules...A Managed Bean must not be: a final class, an abstract class, or a non-static inner class. A Managed Bean may not be serializable unlike a regular JavaBean component.” Thus, the specification for Managed Beans, otherwise known as POJOs or POJO beans, allows extension as in CDI.

CDI Beans

The CDI specification re-defines managed beans as: When running in Java EE, a top-level Java class is a managed bean if it meets the requirements:

• It is not an inner class. • It is a non-abstract class, or is annotated @Decorator. • It does not implement javax.enterprise.inject.spi.Extension. • It is not annotated @Vetoed or in a package annotated @Vetoed. • It has an appropriate constructor, either: the class has a constructor with no parameters, or the class declares a constructor annotated @Inject.

All Java classes that meet these conditions are managed beans and thus no special declaration is required to define a managed bean. Or

if it is defined to be a managed bean by any other Java EE specification and if

• It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.

Bean constructors can have simple-type parameters since simple-types can be injected with the @Inject annotation.

EJBs

EJBs run in an EJB container. The EJB specification says: “A session bean component is a Managed Bean." “The class must have a public constructor that takes no arguments,” it says for both session bean and message-driven bean. Furthermore, it says, “The session bean class is not required to implement the SessionBean interface or the Serializable interface.” For the same reason as JSF beans, that EJB3 dependency injection is basically resource injection, JSF beans do not support constructors with arguments, that is, via dependency injection. However, if the EJB container implements CDI, “ Optionally: The class may have an additional constructor annotated with the Inject annotation, “ it says for both session bean and message-driven bean because, “An EJB packaged into a CDI bean archive and not annotated with javax.enterprise.inject.Vetoed annotation, is considered a CDI-enabled bean.”

A Java Bean is any Java class that satisfies the following three criteria:

  1. It should implement the serializable interface (a Marker interface).
  2. The constructor should be public and have no arguments (what other people call a "no-arg constructor").
  3. It should have getter and setters.

Good to note the serialVersionUID field is important for maintaining object state.

The below code qualifies as a bean:

public class DataDog implements java.io.Serializable {

private static final long serialVersionUID = -3774654564564563L;

private int id;
private String nameOfDog;

// The constructor should NOT have arguments
public DataDog () {}


/** 4. getter/setter */

// Getter(s)
public int getId() {
    return id;
}

public String getNameOfDog() {
    return nameOfDog;
}


// Setter(s)
public void setId(int id) {
    this.id = id;
}

public void setNameOfDog(String nameOfDog) {
    this.nameOfDog = nameOfDog;
}}

It was repeated 6 or 7 times above that there is a no-argument constructor requirement for JavaBeans.

This is WRONG, there is no such requirement, especially in the context of Java Spring.

There is also no mention of that requirement in version (1.01) of the specification that describes the JavaBeanns APIs (https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/). Even more - this specification mentions 'null constructor' only 2 times in the following contexts: "Each customizer should have a null constructor." "Each PropertyEditor should have a null constructor."

So, it does not seem like the authors of the spec don't know or are not willing to use the term "null constructor", still no mention of it for the JavaBeans proper.

If you are familiar with C/Golang, you never heard C bean or Go bean because they have struct keyword, that developers can easily define structure types without writing complicated OOP keywords.

type User struct {
  Name string
  Age int
}

var user User

user.Name = "name"
user.Age = 18

var bytes, err = json.Marshal(user)

It's Java's mistake that lack of struct types, and developers find this bad shortage.

Then Java Bean is invented as just another boring rule to make class pretending struct, peace your editor or compiler won't be crying or yelling about your unsafe access to class members.

POJO (plain old Java object): POJOs are ordinary Java objects, with no restriction other than those forced by the Java Language.

Serialization: It is used to save state of an object and send it across a network. It converts the state of an object into a byte stream. We can recreate a Java object from the byte stream by process called deserialization.

Make your class implement java.io.Serializable interface. And use writeObject() method of ObjectOutputStream class to achive Serialization.

JavaBean class: It is a special POJO which have some restriction (or convention).

  1. Implement serialization
  2. Have public no-arg constructor
  3. All properties private with public getters & setter methods.

Many frameworks - like Spring - use JavaBean objects.

If you want to understand Java-Beans, you first have to understand software-components.

Software components

A software-component is a part of an application that runs a specific operation. A software component can also be part of a service.

A component is:

  • Coupled (has dependencies)
  • Statefull (it saves the states of instance variables)
  • Not standarised, it is designed for a specific use case (main difference between Java-EE Beans)
  • Runs in client machine

Java Beans (Enterprise Beans)

  • Standarised components that run in a Java EE-server
  • Including different business logics to complete a specific service
  • Simplify development of complex multilayer distributed systems

Java Beans are more of a concept to manage big systems. Thats why they need standarization.

Overview

Source

In practice, Beans are just objects which are handy to use. Serializing them means to be able easily to persist them (store in a form that is easily recovered).

Typical uses of Beans in real world:

  • simple reusable objects POJO (Plain Old Java Objects)
  • visual objects
  • Spring uses Beans for objects to handle (for instance, User object that needs to be serialized in session)
  • EJB (Enterprise Java Beans), more complex objects, like JSF Beans (JSF is old quite outdated technology) or JSP Beans

So in fact, Beans are just a convention / standard to expect something from a Java object that it would behave (serialization) and give some ways to change it (setters for properties) in a certain way.

How to use them, is just your invention, but most common cases I enlisted above.

A Java Bean is a component or the basic building block in the JavaBeans architecture. The JavaBeans architecture is a component architecture that benefits from reusability and interoperability of a component-based approach.

A valid component architecture should allow programs to be assembled from software building blocks (Beans in this case), perhaps provided by different vendors and also make it possible for an architect / developer to select a component (Bean), understand its capabilities, and incorporate it into an application.

Since classes/objects are the basic building blocks of an OOP language like Java, they are the natural contenders for being the Bean in the JavaBeans architecture.

The process of converting a plain Java class to a Java bean is actually nothing more than making it a reusable and interoperable component. This would translate into a Java class having abilities like:

  1. controlling the properties, events, and methods of a class that are exposed to another application. (You can have a BeanInfo class that reports only those properties, events and methods that the external application needs.)
  2. persistence (being serialisable or externizable - this would also imply having no-argument constructors, using transient for fields)
  3. ability to register for events and also to generate events (e.g., making use of bound and constraint properties)
  4. customizers (to customise the Bean via GUIs or by providing documentation)

In order for a Java class to be termed a Java bean it is not necessary that they need to possess all the above abilities. Instead, it implies to implement a subset of the above relevant to the context (e.g., a bean in a certain framework may not need customizers, some other bean may not need bound and constrained properties, etc.)

Almost all leading frameworks and libraries in Java adhere to the JavaBeans architecture implicitly, in order to reap the above benefits.

Related