Interface BeanProvider
-
- All Known Implementing Classes:
CollectionBeanProvider
,ConstantBeanProvider
,ConstructorBeanProvider
,FactoryBeanProvider
,LifeCycleBeanProvider
,ListBeanProvider
,MapBeanProvider
,MethodInvocationBeanProvider
,PropertiesBeanProvider
,SetBeanProvider
,SimpleBeanProvider
,SingletonBeanProvider
public interface BeanProvider
Definition of an interface for objects that provide access to beans.
A bean is a plain old Java object that is somehow defined (e.g. its concrete class, some initialization properties, or some methods to be invoked). When the
BeanProvider
is asked for the bean it is responsible for, it has to ensure that it has been created and completely initialized. Then it can be handed over to the calling instance. It is up to a concrete implementation how this is achieved. One implementation can for instance always return the same bean instance, effectively implementing the singleton pattern. Another implementation could create a new bean instance on each request, which would be appropriate for a stateful service bean.The most interesting part of a bean provider is the fact that it can depend on other bean providers (which in turn can have dependencies on further providers and so on). These dependencies are dynamically resolved when a bean is requested, which can lead to a whole bunch of objects being created and initialized. The resulting bean is then fully initialized and ready for service. (These are the well-known concepts of dependency injection and inversion of control (IoC).
The most important method of a
BeanProvider
is thegetBean()
method, which returns the fully initialized bean maintained by this provider. For the proper initialization of the bean and dynamic resolving of dependencies thegetDependencies()
method is also of importance.While providing a reference to the managed bean is naturally the main task of a bean provider, there are some other methods defined in this interface. These methods have a more technical background; they allow the dependency injection framework to effectively manage access to bean stores, especially if they are concurrently used by multiple threads. To better understand these methods some words about synchronization and threading issues are necessary:
An access to the bean provided by a
BeanProvider
is automatically synchronized by the framework. This means that until the bean is completely created and initialized, no other thread can access this provider. If there are cyclic references in the dependency graph however (e.g. bean A depends on bean B, which depends on bean C, which again depends on bean A), thegetBean()
method can be entered again by the same thread. An implementation should be aware of this. The invocation of a bean provider'sgetBean()
method is also called a transaction. If the bean store is concurrently accessed by other threads, it has to be ensured that the whole initialization process of a bean is not disturbed by other threads. The framework takes care about this. With the additional methods defined by this interface aBeanProvider
implementation can obtain information about the start and the end of such transactions.When an application is about to shut down or when a
BeanStore
is closed, it is often necessary to do some clean up. For beans created by the framework - especially singleton service beans - it may be required to invoke a specific shutdown method, for instance if the bean is a database connection pool or something like that. For this purpose theBeanProvider
interface defines theshutdown()
method. Here a concrete implementation can place code for cleaning up the beans created by it.- Version:
- $Id: BeanProvider.java 205 2012-01-29 18:29:57Z oheger $
- Author:
- Oliver Heger
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description Object
getBean(DependencyProvider dependencyProvider)
Returns the bean managed by this provider.Class<?>
getBeanClass(DependencyProvider dependencyProvider)
Returns the class of the bean managed by this provider.Set<Dependency>
getDependencies()
Returns a set with the descriptions of the beans this provider depends on.Long
getLockID()
Returns the ID of the transaction that locked this bean provider.boolean
isBeanAvailable()
Checks whether the bean managed by this provider can now be retrieved.void
setLockID(Long lid)
Locks or unlocks thisBeanProvider
.void
shutdown(DependencyProvider dependencyProvider)
Notifies thisBeanProvider
that it (and the bean(s) created by it) is no longer needed.
-
-
-
Method Detail
-
getBean
Object getBean(DependencyProvider dependencyProvider)
Returns the bean managed by this provider. This is the main method of a
BeanProvider
. A concrete implementation can do whatever is necessary to obtain the requested bean. Depending on the provider's semantic it can decide whether the bean is cached after it has been created, or whether for each request a new bean has to be created.The passed in reference to a
DependencyProvider
can be used for obtaining needed dependencies. This method will be automatically synchronized by the framework. However if there are cyclic dependencies, querying theDependencyProvider
may cause the method to be entered again. An implementation must be aware of this to avoid endless loops.If a problem occurs when creating and initializing the bean, an implementation should throw a
exception.InjectionException
- Parameters:
dependencyProvider
- the dependency provider- Returns:
- the bean managed by this provider
-
getBeanClass
Class<?> getBeanClass(DependencyProvider dependencyProvider)
Returns the class of the bean managed by this provider. Clients may query beans based on their class. So it becomes necessary to ask a provider for the bean class without having to create the bean first. ADependencyProvider
is passed in that can be used for resolving the class (in case only the class name is known to the provider)- Parameters:
dependencyProvider
- the dependency provider, which can be used for resolving the bean class- Returns:
- the class of the bean managed by this provider
-
getDependencies
Set<Dependency> getDependencies()
Returns a set with the descriptions of the beans this provider depends on. These are typically beans the managed bean is to be initialized with through dependency injection. This method is called once by the framework whenever a transaction starts (i.e. when client code queries either this bean or a bean that depends on this provider). Its return value need not be constant over time (for instance a provider that always returns the same bean does not need any dependencies any more after the bean has been initialized on first access).- Returns:
- a set with the dependency descriptions of the beans this bean provider depends on (can be null if there are no dependencies)
- See Also:
Dependency
-
getLockID
Long getLockID()
Returns the ID of the transaction that locked this bean provider. A transaction locks eachBeanProvider
it depends on, so that it cannot be concurrently accessed by another thread. This is done using thesetLockID()
. An implementation will typically store the value passed in here and return it ingetLockID()
. However if a concrete implementation does not need any synchronization (e.g. because it only returns a constant object), it can always return null here.- Returns:
- the ID of the locking transaction or null if there is none
-
setLockID
void setLockID(Long lid)
Locks or unlocks thisBeanProvider
. This method is called with the ID of the current transaction to mark this provider as blocked. After that it cannot be accessed by a different thread until the locking transaction ends. Before it ends it will call this method again with a value of null. This method, in conjunction with thegetLockID()
method, is related to the implementation of synchronized access to bean providers. ABeanProvider
implementation that requires synchronization should store the value passed in here in a member field and return it in thegetLockID()
method. An implementation that is thread-safe can leave this method empty and return always null ingetLockID()
.- Parameters:
lid
- the ID of the locking transaction- See Also:
getLockID()
-
isBeanAvailable
boolean isBeanAvailable()
Checks whether the bean managed by this provider can now be retrieved. This method can be used for detecting cyclic references: A bean may need other beans as arguments for its creation (e.g. for calling its constructor). This may cause the creation of these dependent beans. If one of these depends on the original bean, there is a cyclic dependency. Complex bean providers supporting enhanced bean creation and initialization should implement this method to return false if their managed bean is currently in the creation phase and thus does not really exist yet. A caller may then decide to try again later when the creation is complete. Simple bean providers can always return true.- Returns:
- a flag whether the managed bean is available
-
shutdown
void shutdown(DependencyProvider dependencyProvider)
Notifies thisBeanProvider
that it (and the bean(s) created by it) is no longer needed. A concrete implementation can use this method to perform some cleanup. It is also an opportunity for invoking a shutdown method on the bean created by this provider. Typically this method will be called when theBeanStore
thisBeanProvider
belongs to is closed.- Parameters:
dependencyProvider
- theDependencyProvider
-
-