Factory and manager components
We often need to work with objects that are not Seam components. But we still want to be able to inject them into our components using @In
and use them in value and method binding expressions, etc. Sometimes, we even need to tie them into the Seam context lifecycle (@Destroy
, for example). So the Seam contexts can contain objects which are not Seam components, and Seam provides a couple of nice features that make it easier to work with non-component objects bound to contexts.
The
factory component pattern
lets a Seam component act as the instantiator for a non-component object. A
factory method
will be called when a context variable is referenced but has no value bound to it. We define factory methods using the @Factory
annotation. The factory method binds a value to the context variable, and determines the scope of the bound value. There are two styles of factory method. The first style returns a value, which is bound to the context by Seam:
@Factory(scope=CONVERSATION)
public List<Customer> getCustomerList() {
return ... ;
}
The second style is a method of type void
which binds the value to the context variable itself:
@DataModel List<Customer> customerList;
@Factory("customerList")
public void initCustomerList() {
customerList = ... ;
}
In both cases, the factory method is called when we reference the customerList
context variable and its value is null, and then has no further part to play in the lifecycle of the value. An even more powerful pattern is the
manager component pattern
. In this case, we have a Seam component that is bound to a context variable, that manages the value of the context variable, while remaining invisible to clients.
A manager component is any component with an @Unwrap
method. This method returns the value that will be visable to clients, and is called
every time
a context variable is referenced.
@Name("customerList")
@Scope(CONVERSATION)
public class CustomerListManager
{
...
@Unwrap
public List<Customer> getCustomerList() {
return ... ;
}
}
This pattern is especially useful if we have some heavyweight object that needs a cleanup operation when the context ends. In this case, the manager component may perform cleanup in the @Destroy
method.