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 the
getBean()
method, which returns the fully initialized bean
maintained by this provider. For the proper initialization of the bean and
dynamic resolving of dependencies the getDependencies()
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), the getBean()
method can be entered again by the
same thread. An implementation should be aware of this. The invocation of a
bean provider's getBean()
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 a BeanProvider
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 the BeanProvider
interface defines the shutdown()
method. Here a concrete
implementation can place code for cleaning up the beans created by it.
Modifier and Type | Method and 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 this
BeanProvider . |
void |
shutdown(DependencyProvider dependencyProvider)
Notifies this
BeanProvider that it (and the bean(s) created by
it) is no longer needed. |
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 the DependencyProvider
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
dependencyProvider
- the dependency providerClass<?> getBeanClass(DependencyProvider dependencyProvider)
DependencyProvider
is passed in that can be used for
resolving the class (in case only the class name is known to the
provider)dependencyProvider
- the dependency provider, which can be used for
resolving the bean classSet<Dependency> getDependencies()
Dependency
Long getLockID()
BeanProvider
it depends on, so that
it cannot be concurrently accessed by another thread. This is done using
the setLockID()
. An implementation will typically store
the value passed in here and return it in getLockID()
.
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.void setLockID(Long lid)
BeanProvider
. 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 the
getLockID()
method, is related to the implementation of
synchronized access to bean providers. A BeanProvider
implementation that requires synchronization should store the value
passed in here in a member field and return it in the
getLockID()
method. An implementation that is thread-safe
can leave this method empty and return always null in
getLockID()
.lid
- the ID of the locking transactiongetLockID()
boolean isBeanAvailable()
void shutdown(DependencyProvider dependencyProvider)
BeanProvider
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 the BeanStore
this BeanProvider
belongs to
is closed.dependencyProvider
- the DependencyProvider
Copyright © 2016 The JGUIraffe Team. All rights reserved.