BeanFactory和FactoryBean的区别

1. BeanFactory

BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。在 Spring 代码中,BeanFactory 只是个接口,并不是 IOC 容器的具体实现,但是 Spring 容器给出了很多种实现,如 DefaultListableBeanFactory 、XmlBeanFactory 、 ApplicationContext、ClassPathXmlApplicationContext 等,都是附加了某种功能的实现。

package org.springframework.beans.factory;  
import org.springframework.beans.BeansException;  
public interface BeanFactory {  
    String FACTORY_BEAN_PREFIX = "&";  
    Object getBean(String name) throws BeansException;  
     T getBean(String name, Class requiredType) throws BeansException;  
     T getBean(Class 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

FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

package org.springframework.beans.factory;  
public interface FactoryBean {  
    T getObject() throws Exception;  
    Class getObjectType();  
    boolean isSingleton();  
} 

下面是一个应用FactoryBean的例子


    
   
    
   
 
   
  
 
   
    
  

FactoryBean的实现类

import org.springframework.beans.factory.FactoryBean;
 
public class FactoryBeanPojo implements FactoryBean{
    private String type;
 
    @Override
    public Object getObject() throws Exception {
        if("student".equals(type)){
            return new Student();           
        }else{
            return new School();
        }
        
    }
 
    @Override
    public Class getObjectType() {
        return School.class;
    }
 
    @Override
    public boolean isSingleton() {
        return true;
    }
 
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
}

普通的bean

public class School {
    private String schoolName;
    private String address;
    private int studentNumber;
    public String getSchoolName() {
        return schoolName;
    }
    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getStudentNumber() {
        return studentNumber;
    }
    public void setStudentNumber(int studentNumber) {
        this.studentNumber = studentNumber;
    }
    @Override
    public String toString() {
        return "School [schoolName=" + schoolName + ", address=" + address
                + ", studentNumber=" + studentNumber + "]";
    }

测试类

import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.spring.bean.FactoryBeanPojo;
 
public class FactoryBeanTest {
    public static void main(String[] args){
        String url = "com/spring/config/BeanConfig.xml";
        ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
        Object school=  cpxa.getBean("factoryBeanPojo");
        FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");
        System.out.println(school.getClass().getName());
        System.out.println(factoryBeanPojo.getClass().getName());
    }
}

输出的结果:

十一月 16, 2016 10:28:24 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e8ee5c0: startup date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml]
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy
com.spring.bean.Student
com.spring.bean.FactoryBeanPojo

从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。

3.BeanFactory和FactoryBean的区别

BeanFactory和FactoryBean其实没有什么比较性的,只是两者的名称特别接近,所以有时候会拿出来比较一番,BeanFactory是提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范,FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类,要想深入准确的理解FactoryBean,只有去读读Spring源码了。

原文:https://blog.csdn.net/wangbiao007/article/details/53183764

你可能感兴趣的:(BeanFactory和FactoryBean的区别)