BeanFactory is a workhorse that initializes beans and calls their lifecycle methods. It should be noted that most lifecycle methods only apply to singleton beans. Spring cannot manage prototype (non-singleton) lifecycles. This is because, after they’re created, prototypes are handed off to the client and the container loses track of it. For prototypes, Spring is really just a replacement for the “new” operator.
A BeanFactory is represented by the interface org.springframework.beans.factory.BeanFactory, and it is having multiple implementations. The most commonly used simple BeanFactory implementation is org.springframework.beans.factory.xml.XmlBeanFactory. (This should be qualified with the reminder that ApplicationContexts are a subclass of BeanFactory, and most users end up using XML variants of ApplicationContext).
Although for most scenarios, almost all user code managed by the BeanFactory does not have to be aware of the BeanFactory, the BeanFactory does have to be instantiated somehow. This can happen via explicit user code such as:
Resource res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
or
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
or
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) appContext;
Beans are lazily loaded into bean factories, meaning that while the bean factory will immediately load the bean definitions (the description of beans and their properties), the beans themselves will not be instantiated until they are needed.
BeanDefinition includes
1. class name which is normally the actual implementation class of the bean being described in the bean definition. However, if the bean is to be constructed by calling a static factory method instead of using a normal constructor, this will actually be the class name of the factory class.
2. bean behavioral configuration elements, which state how the bean should behave in the container (i.e. prototype or singleton, autowiring mode, dependency checking mode, initialization and destruction methods)
3. constructor arguments and property values to set in the newly created bean. An example would be the number of connections to use in a bean that manages a connection pool (either specified as a property or as a constructor argument), or the pool size limit.
4. other beans a bean needs to do its work, i.e. collaborators (also specified as properties or as constructor arguments). These can also be called dependencies.
In the much more common case where the BeanFactory itself directly creates the bean by calling its constructor (equivalent to Java code calling new), the class attribute specifies the class of the bean to be constructed. In the less common case where the BeanFactory calls a static factory method on a class to create the bean, the class attribute specifies the actual class containing the static factory method. (the type of the returned bean from the static factory method may be the same class or another class entirely, it doesn't matter).
1. Bean creation via constructor
When creating a bean using the constructor approach, all normal classes are usable by Spring and compatible with Spring. That is, the class being created does not need to implement any specific interfaces or be coded in a specific fashion. Just specifying the bean class should be enough. However, depending on what type of IoC you are going to use for that specific bean, you may need a default (empty) constructor.
Note : Additionally, the BeanFactory isn't limited to just managing true JavaBeans, it is also able to manage virtually any class you want it to manage. Most people using Spring prefer to have actual JavaBeans (having just a default (no-argument) constructor and appropriate setters and getters modeled after the properties) in the BeanFactory, but it it's also possible to have more exotic non-bean-style classes in your BeanFactory. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, no worries, Spring can manage it as well.
Using the XmlBeanFactory you can specify your bean class as follows:
<bean id="myBean"
class="spring.MyBean"/>
2. Bean creation via static factory method
When defining a bean which is to be created using a static factory method, along with the class attribute which specifies the class containing the static factory method, another attribute named factory-method is needed to specify the name of the factory method itself. Spring expects to be able to call this method and get back a live object, which from that point on is treated as if it had been created normally via a constructor. One use for such a bean definition is to call static factories in legacy code.
Following is an example of a bean definition which specifies that the bean is to be created by calling a factory-method. Note that the definition does not specify the type (class) of the returned object, only the class containing the factory method. In this example, createInstance must be a static method.
<bean id="myBean"
class="spring.MyBean"
factory-method="createInstance"/>
3. Bean creation via instance factory method
In a fashion similar to instantiation via a static factory method, instantiation using an instance factory method is where a non-static method of an existing bean from the container is invoked to create a new bean. To use this mechanism, the 'class' attribute must be left empty, and the 'factory-bean' attribute must specify the name of a bean in the current (or parent/ancestor) container that contains the instance method that is to be invoked to create the object. The name of the factory method itself must be set using the 'factory-method' attribute.
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="com.foo.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createService"/>
To singleton or not to singleton
Beans are defined to be deployed in one of two modes: singleton or non-singleton (prototype). When a bean is a singleton, only one shared instance of the bean will be managed and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned.
The non-singleton, prototype mode of a bean deployment results in the creation of a new bean instance every time a request for that specific bean is done. This is ideal for situations where for example each user needs an independent user object or something similar.
Beans are deployed in singleton mode by default, unless you specify otherwise. Keep in mind that by changing the type to non-singleton (prototype), each request for a bean will result in a newly created bean and this might not be what you actually want. So only change the mode to prototype when absolutely necessary.
In the example below, two beans are declared of which one is defined as a singleton, and the other one is a non-singleton (prototype). myBean is created each and every time a client asks the BeanFactory for this bean, while myBeanAgain is only created once; a reference to the exact same instance is returned on each request for this bean.
<bean id="myBean"
class="spring.MyBean" singleton="false"/>
<bean name="myBeanAgain"
class="spring.MyBeanAgain" singleton="true"/>
A BeanFactory is essentially nothing more than the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. The BeanFactory enables you to read bean definitions and access them using the bean factory. When using just the BeanFactory you would create one and read in some bean definitions in the XML format as follows:
InputStream is = new FileInputStream("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
The BeanFactory interface has only five methods for clients to call:
boolean containsBean(String): returns true if the BeanFactory contains a bean definition or bean instance that matches the given name
Object getBean(String): returns an instance of the bean registered under the given name. Depending on how the bean was configured by the BeanFactory configuration, either a singleton and thus shared instance or a newly created bean will be returned. A BeansException will be thrown when either the bean could not be found (in which case it'll be a NoSuchBeanDefinitionException), or an exception occurred while instantiating and preparing the bean
Object getBean(String,Class): returns a bean, registered under the given name. The bean returned will be cast to the given Class. If the bean could not be cast, corresponding exceptions will be thrown (BeanNotOfRequiredTypeException). Furthermore, all rules of the getBean(String) method apply (see above)
boolean isSingleton(String): determines whether or not the bean definition or bean instance registered under the given name is a singleton or a prototype. If no bean corresponding to the given name could not be found, an exception will be thrown (NoSuchBeanDefinitionException)
String[] getAliases(String): Return the aliases for the given bean name, if any were defined in the bean definition
Hope it will be useful.....
4 comments:
Thanks Sneha.
Very nice article on BeanFactory class.
Regards
Prashant
http://www.prashantaboutindia.blogspot.com/
hi sneha , i want to know that what is the use of proxy bean factory in spring
Very clear explanation and useful. Thanks.
FacesContext context= FacesContext.getCurrentInstance();
WebApplicationContext appContext =
FacesContextUtils.getRequiredWebApplicationContext(context);
I am using above code for using Application Context.When i am using this FacesContext.getCurrentInstance() function returns null value when it is called at startup.Do you know the reason for this.If so please reply to amithvuce@gmail.com
Post a Comment