Components and contexts
4.2 Sorting out components
The term component has been used to mean many things. In my attempts to describe it to you, I found it difficult to locate a universal definition, likely because one doesn’t exist. In theory, a component is supposedly a module that can be plugged into an application in the same way that one Lego piece is attached to another Lego piece to form a larger structure. As a person who makes a living developing software, I’m sure you’ll agree that software components are a bit more complicated than Legos.
Definitions and intentions don’t matter anyway. What matters is what the word means to you as a software developer. Up to now, we’ve assumed that a component is equivalent to a JSF managed bean. Although a Seam component can stand in for a JSF managed bean, the definition of a component is broader. A component is a set of instructions, stored in a container, that is used to create objects whose life cycle is man-aged by the container. After taking a deeper, but brief dive into this somewhat abstract term, I promise that this component jargon will make sense. It’s all in the naming.
4.2.1 Components vs. component instances
A component is a set of instructions, or a blueprint, for creating an object. It supple-ments the Java class definition. Each component is assigned a name, which is used to address the component. Table 4.3 lists several containers and how the components they manage are declared.
When a class becomes a component, it gains access to whatever services the con-tainer has to provide. For instance, methods on EJB session beans are automatically wrapped in transactions; servlet components and JSF managed beans have access to
Table 4.2 The @Synchronized annotation Name: Synchronized
Purpose: Protects a component against concurrent access Target: TYPE (class)
Attribute Type Function
timeout long The duration of time in milliseconds that a thread should be made to wait before an IllegalStateException is thrown. Default: 1000.
web-tier resource injections; Spring beans are injected with other Spring beans when instantiated. As you can see, being a component gives a class special privileges.
Great, so now you know what a component is. But since this book is about Seam, let’s focus on Seam components. A Seam component holds
■ Metadata pertaining to the creation of an instance
■ Life-cycle methods
■ Initial property values or object references Seam creates component instances from the component definition, as figure 4.1 illus-trates. When your application interacts with a component, what it’s really invoking is an instance of that component.
Once an instance of a component is created, it’s stored as an attribute in its desig-nated context under the name of the component, forming what is known as a context variable. An instance of a component is just a Java object, with one exception. It is strung with interceptors that allow Seam to keep tabs on it and manage its life cycle.
Once in control, Seam is able to transparently weave behavior into the object when it is invoked. You may recognize this technique as Aspect-Oriented Programming (AOP). The idea of AOP is to handle cross-cutting concerns that would otherwise appear as boilerplate code or tie the code to a particular environment. With AOP at work, a method call isn’t just a method call. More goes on around each invocation, and that means you get more for less work.
Table 4.3 A sampling of component containers and how components are defined in each one
Container How classes become components
Seam Annotated with @Name or declared in components.xml
EJB Annotated with @Stateful, @Stateless, @MessageDriven or declared in ejb-jar.xml (annotations only relevant for EJB 3)
JSF Declared as managed beans in faces-config.xml Spring Declared as a Spring bean in applicationContext.xml Servlet container Servlets, filters, and listeners declared in web.xml
Component vs. component instance: making the distinction
The relationship between a component and a component instance parallels the rela-tionship between a Java class and a Java object, respectively. Seam even uses the Component type to describe a component definition in the same way that Java uses the Class type to describe a class definition.
C o m p o n e n t C o m p o n e n t
In s ta n c e
Figure 4.1 Component instances are created from components by the Seam container
Seam determines how to handle the object based on the instructions provided in annotations. The behavior that Seam applies includes injecting dependencies, manag-ing transactions, enforcmanag-ing security constraints, invokmanag-ing life-cycle methods, and han-dling events triggered by the component, to mention a few. That should sound similar to how EJB works as it inspired this design.
4.2.2 Seam manages components
There’s another important characteristic of a component: a component is managed by the Seam container. The container hands out an instance of a component when the name assigned to the component is requested, as shown in figure 4.2. When this request comes in, Seam first tries to locate an existing instance. If one can’t be found, Seam will create one (if asked to do so). The instance is then returned to the requester.
With Seam in control, you no longer have to create instances by instantiating the Java class explicitly using the Java new operator. That isn’t to say that you can’t—but to get all of the enhancements that Seam applies to the object via AOP (which happens during the newInstance() routine in figure 4.2), you must allow Seam to create the instance for you. In that regard, the Seam container is a factory for component instances, which uses the component definitions as the schematics for how to create those instances.
The translation from component to component instance happens more often in a Seam application than it does in other lightweight containers such as Spring. That’s because context is so important in Seam. In Seam, component instances come and go along with the life cycle of the contexts in which they are stored. As you learned ear-lier, Seam’s contexts have varying life spans (one with no life span at all). More often than not, components in Seam are associated with stateful contexts, which means they don’t invariably hang around for the lifetime of the application.
Instance creation takes place in the Spring container just as it does in Seam, but you typically don’t give it much thought. That’s because Spring primarily uses single-ton beans, whose lifetime is tied to that of the application. What’s so interesting about Seam is that it’s perfectly natural to create an object and inject dependencies into it at an arbitrary point in time, rather than when the application starts.
S e a m C o n ta in e r A p p lic a tio n
g e tIn s ta n c e (n a m e )
n e w In s ta n c e ()
S ta te fu l C o n te x ts
lo o k u p (n a m e )
o p t [n o t fo u n d ]
in s ta n c e
in s ta n c e
Figure 4.2 Sequence diagram of a component instance being requested from the Seam container
NOTE Spring does provide prototype beans that are created each time they’re referenced, but they are arguably more difficult to use than Seam’s con-textual components.
We haven’t yet addressed how Seam components are defined. To be more concise, how do the components get into the Seam container? Read on to find out.