View Javadoc

1   /*
2    * Copyright 2006-2016 The JGUIraffe Team.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.jguiraffe.di;
17  
18  import java.util.Set;
19  
20  /**
21   * <p>
22   * Definition of an interface for objects that provide access to beans.
23   * </p>
24   * <p>
25   * A <em>bean</em> is a plain old Java object that is somehow defined (e.g. its
26   * concrete class, some initialization properties, or some methods to be
27   * invoked). When the <code>BeanProvider</code> is asked for the bean it is
28   * responsible for, it has to ensure that it has been created and completely
29   * initialized. Then it can be handed over to the calling instance. It is up to
30   * a concrete implementation how this is achieved. One implementation can for
31   * instance always return the same bean instance, effectively implementing the
32   * <em>singleton</em> pattern. Another implementation could create a new bean
33   * instance on each request, which would be appropriate for a stateful service
34   * bean.
35   * </p>
36   * <p>
37   * The most interesting part of a bean provider is the fact that it can depend
38   * on other bean providers (which in turn can have dependencies on further
39   * providers and so on). These dependencies are dynamically resolved when a bean
40   * is requested, which can lead to a whole bunch of objects being created and
41   * initialized. The resulting bean is then fully initialized and ready for
42   * service. (These are the well-known concepts of <em>dependency injection</em>
43   * and <em>inversion of control (IoC)</em>.
44   * </p>
45   * <p>
46   * The most important method of a <code>BeanProvider</code> is the
47   * <code>getBean()</code> method, which returns the fully initialized bean
48   * maintained by this provider. For the proper initialization of the bean and
49   * dynamic resolving of dependencies the <code>getDependencies()</code> method
50   * is also of importance.
51   * </p>
52   * <p>
53   * While providing a reference to the managed bean is naturally the main task of
54   * a bean provider, there are some other methods defined in this interface.
55   * These methods have a more technical background; they allow the dependency
56   * injection framework to effectively manage access to bean stores, especially
57   * if they are concurrently used by multiple threads. To better understand these
58   * methods some words about synchronization and threading issues are necessary:
59   * </p>
60   * <p>
61   * An access to the bean provided by a <code>BeanProvider</code> is
62   * automatically synchronized by the framework. This means that until the bean
63   * is completely created and initialized, no other thread can access this
64   * provider. If there are cyclic references in the dependency graph however
65   * (e.g. bean A depends on bean B, which depends on bean C, which again depends
66   * on bean A), the <code>getBean()</code> method can be entered again by the
67   * same thread. An implementation should be aware of this. The invocation of a
68   * bean provider's <code>getBean()</code> method is also called a
69   * <em>transaction</em>. If the bean store is concurrently accessed by other
70   * threads, it has to be ensured that the whole initialization process of a bean
71   * is not disturbed by other threads. The framework takes care about this. With
72   * the additional methods defined by this interface a <code>BeanProvider</code>
73   * implementation can obtain information about the start and the end of such
74   * transactions.
75   * </p>
76   * <p>
77   * When an application is about to shut down or when a {@code BeanStore} is
78   * closed, it is often necessary to do some clean up. For beans created by the
79   * framework - especially singleton service beans - it may be required to invoke
80   * a specific shutdown method, for instance if the bean is a database connection
81   * pool or something like that. For this purpose the {@code BeanProvider}
82   * interface defines the {@code shutdown()} method. Here a concrete
83   * implementation can place code for cleaning up the beans created by it.
84   * </p>
85   *
86   * @author Oliver Heger
87   * @version $Id: BeanProvider.java 205 2012-01-29 18:29:57Z oheger $
88   */
89  public interface BeanProvider
90  {
91      /**
92       * <p>
93       * Returns the bean managed by this provider. This is the main method of a
94       * <code>BeanProvider</code>. A concrete implementation can do whatever
95       * is necessary to obtain the requested bean. Depending on the provider's
96       * semantic it can decide whether the bean is cached after it has been
97       * created, or whether for each request a new bean has to be created.
98       * </p>
99       * <p>
100      * The passed in reference to a <code>DependencyProvider</code> can be
101      * used for obtaining needed dependencies. This method will be automatically
102      * synchronized by the framework. However if there are cyclic dependencies,
103      * querying the <code>DependencyProvider</code> may cause the method to be
104      * entered again. An implementation must be aware of this to avoid endless
105      * loops.
106      * </p>
107      * <p>
108      * If a problem occurs when creating and initializing the bean, an
109      * implementation should throw a <code>{@link InjectionException}</code>
110      * exception.
111      * </p>
112      *
113      * @param dependencyProvider the dependency provider
114      * @return the bean managed by this provider
115      */
116     Object getBean(DependencyProvider dependencyProvider);
117 
118     /**
119      * Returns the class of the bean managed by this provider. Clients may query
120      * beans based on their class. So it becomes necessary to ask a provider for
121      * the bean class without having to create the bean first. A
122      * <code>DependencyProvider</code> is passed in that can be used for
123      * resolving the class (in case only the class name is known to the
124      * provider)
125      *
126      * @param dependencyProvider the dependency provider, which can be used for
127      * resolving the bean class
128      * @return the class of the bean managed by this provider
129      */
130     Class<?> getBeanClass(DependencyProvider dependencyProvider);
131 
132     /**
133      * Returns a set with the descriptions of the beans this provider depends
134      * on. These are typically beans the managed bean is to be initialized with
135      * through dependency injection. This method is called once by the framework
136      * whenever a transaction starts (i.e. when client code queries either this
137      * bean or a bean that depends on this provider). Its return value need not
138      * be constant over time (for instance a provider that always returns the
139      * same bean does not need any dependencies any more after the bean has been
140      * initialized on first access).
141      *
142      * @return a set with the dependency descriptions of the beans this bean
143      * provider depends on (can be <b>null</b> if there are no dependencies)
144      * @see Dependency
145      */
146     Set<Dependency> getDependencies();
147 
148     /**
149      * Returns the ID of the transaction that locked this bean provider. A
150      * transaction locks each <code>BeanProvider</code> it depends on, so that
151      * it cannot be concurrently accessed by another thread. This is done using
152      * the <code>setLockID()</code>. An implementation will typically store
153      * the value passed in here and return it in <code>getLockID()</code>.
154      * However if a concrete implementation does not need any synchronization
155      * (e.g. because it only returns a constant object), it can always return
156      * <b>null</b> here.
157      *
158      * @return the ID of the locking transaction or <b>null</b> if there is
159      * none
160      */
161     Long getLockID();
162 
163     /**
164      * Locks or unlocks this <code>BeanProvider</code>. This method is called
165      * with the ID of the current transaction to mark this provider as blocked.
166      * After that it cannot be accessed by a different thread until the locking
167      * transaction ends. Before it ends it will call this method again with a
168      * value of <b>null</b>. This method, in conjunction with the
169      * <code>getLockID()</code> method, is related to the implementation of
170      * synchronized access to bean providers. A <code>BeanProvider</code>
171      * implementation that requires synchronization should store the value
172      * passed in here in a member field and return it in the
173      * <code>getLockID()</code> method. An implementation that is thread-safe
174      * can leave this method empty and return always <b>null</b> in
175      * <code>getLockID()</code>.
176      *
177      * @param lid the ID of the locking transaction
178      * @see #getLockID()
179      */
180     void setLockID(Long lid);
181 
182     /**
183      * Checks whether the bean managed by this provider can now be retrieved.
184      * This method can be used for detecting cyclic references: A bean may need
185      * other beans as arguments for its creation (e.g. for calling its
186      * constructor). This may cause the creation of these dependent beans. If
187      * one of these depends on the original bean, there is a cyclic dependency.
188      * Complex bean providers supporting enhanced bean creation and
189      * initialization should implement this method to return <b>false</b> if
190      * their managed bean is currently in the creation phase and thus does not
191      * really exist yet. A caller may then decide to try again later when the
192      * creation is complete. Simple bean providers can always return <b>true</b>.
193      *
194      * @return a flag whether the managed bean is available
195      */
196     boolean isBeanAvailable();
197 
198     /**
199      * Notifies this {@code BeanProvider} that it (and the bean(s) created by
200      * it) is no longer needed. A concrete implementation can use this method to
201      * perform some cleanup. It is also an opportunity for invoking a shutdown
202      * method on the bean created by this provider. Typically this method will
203      * be called when the {@code BeanStore} this {@code BeanProvider} belongs to
204      * is closed.
205      *
206      * @param dependencyProvider the {@code DependencyProvider}
207      */
208     void shutdown(DependencyProvider dependencyProvider);
209 }