The difference between BeanFactory and FactoryBean in spring
Difference: BeanFactory is a Factory, that is, IOC container or object factory, and FactoryBean is a Bean. In Spring, all beans are managed by the BeanFactory (that is, the IOC container). But for FactoryBean, this bean is not a simple bean, but a factory bean that can produce or modify objects. Its implementation is similar to the factory pattern and decorator pattern in the design pattern.
1. BeanFactory
BeanFactory defines the most basic form of the IOC container, and provides the most basic interface that the IOC container should comply with, that is , the lowest level and the most basic programming specification that Spring IOC complies with. In Spring code, BeanFactory is just an interface, not a specific implementation of the IOC container, but the Spring container provides many implementations, such as DefaultListableBeanFactory , XmlBeanFactory , ApplicationContext , etc., all of which are implementations with additional functions.
- package org.springframework.beans.factory;
- import org.springframework.beans.BeansException;
- public interface BeanFactory {
- String FACTORY_BEAN_PREFIX = "&" ;
- Object getBean(String name) throws BeansException;
- <T> T getBean(String name, Class<T> requiredType) throws BeansException;
- <T> T getBean(Class<T> requiredType) throws BeansException;
- Object getBean(String name, Object... args) throws BeansException;
- boolean containsBean(String name);
- boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
- boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
- boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
- Class<?> getType(String name) throws NoSuchBeanDefinitionException;
- String[] getAliases(String name);
- }
2. FactoryBean In
general, Spring uses the class attribute of <bean> to specify the implementation class to instantiate beans through the reflection mechanism. In some cases, the process of instantiating beans is more complicated. A lot of configuration information is provided in . The flexibility of the configuration method is limited, and a simple solution may be obtained by using the encoding method. Spring provides a factory class interface of org.springframework.bean.factory.FactoryBean for this purpose, and users can customize the logic of instantiating beans by implementing this interface.
The FactoryBean interface occupies an important position for the Spring framework, and Spring itself provides more than 70 FactoryBean implementations. They hide the details of instantiating some complex beans and bring convenience to upper-layer applications. Since Spring 3.0, FactoryBean began to support generics, that is, the interface declaration was changed to the form of FactoryBean<T>
- package org.springframework.beans.factory;
- public interface FactoryBean<T> {
- T getObject() throws Exception;
- Class<?> getObjectType();
- boolean isSingleton();
- }
TgetObject(): Returns the Bean instance created by FactoryBean. If isSingleton() returns true, the instance will be placed in the single-instance cache pool in the Spring container;
booleanisSingleton(): Returns whether the scope of the Bean instance created by FactoryBean is singleton or prototype;
Class<T>getObjectType(): Returns the Bean type created by FactoryBean.
When the implementation class configured by the class attribute of <bean> in the configuration file is FactoryBean, what is returned by the getBean() method is not the FactoryBean itself, but the object returned by the FactoryBean#getObject() method, which is equivalent to the FactoryBean#getObject() proxy the getBean() method.
Example: If the <bean> of Car below is configured in the traditional way, each property of Car corresponds to a <property> element tag.
- package com.baobaotao.factorybean;
- public class Car {
- private int maxSpeed ;
- private String brand ;
- private double price ;
- public int getMaxSpeed() {
- return this .maxSpeed ;
- }
- public void setMaxSpeed( int maxSpeed ) {
- this.maxSpeed = maxSpeed;
- }
- public String getBrand() {
- return this.brand ;
- }
- public void setBrand( String brand ) {
- this.brand = brand;
- }
- public double getPrice() {
- return this . price ;
- }
- public void setPrice( double price ) {
- this.price = price;
- }
- }
- package com.baobaotao.factorybean;
- import org.springframework.beans.factory.FactoryBean;
- public class CarFactoryBean implements FactoryBean<Car> {
- private String carInfo ;
- public Car getObject () throws Exception {
- Car car = new Car () ;
- String[] infos = carInfo.split( "," );
- car.setBrand(infos[ 0 ]);
- car.setMaxSpeed(Integer.valueOf(infos[ 1 ]));
- car.setPrice( Double.valueOf( infos[ 2 ]) ) ;
- return car;
- }
- public Class<Car> getObjectType () {
- return Car.class ; _
- }
- public boolean isSingleton() {
- return false ;
- }
- public String getCarInfo () {
- return this .carInfo ;
- }
- // Accept comma separator to set attribute information
- public void setCarInfo( String carInfo ) {
- this.carInfo = carInfo;
- }
- }
<beanid="car"class="com.baobaotao.factorybean.CarFactoryBean"
P:carInfo="Ferrari,400 ,2000000"/>
When calling getBean("car"), Spring finds that CarFactoryBean implements the interface of FactoryBean through the reflection mechanism, and then the Spring container calls the interface method CarFactoryBean#getObject() method to return. If you want to get an instance of CarFactoryBean, you need to add a "&" prefix before the beanName when using the getBean(beanName) method: such as getBean("&car");
3. The difference between
BeanFactory is a Factory, that is, IOC container or object factory, and FactoryBean is a Bean. In Spring, all beans are managed by the BeanFactory (that is, the IOC container). But for FactoryBean, this bean is not a simple bean, but a factory bean that can produce or modify objects. Its implementation is similar to the factory pattern and decorator pattern in the design pattern.