BeanFactory

所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean方法等。

BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它是负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
//返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式
//将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
    Object getBean(String var1) throws BeansException;
// 返回以给定名称注册的bean实例,并转换为给定class类型
    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
//Spring容器中是否存在该对象
    boolean containsBean(String var1);
//判断给定名称的bean定义是否为单例模式
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

//判断bean对象是否为多例对象
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
//判断name值获取出来的bean与typeToMath是否匹配
    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
//判断name值获取出来的bean与typeToMath是否匹配
    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
//返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
///返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
    @Nullable
    Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;
//返回给定bean名称的所有别名 
    String[] getAliases(String var1);
}

FactoryBean

FactoryBean是SpringIOC容器创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式。

一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式。

以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

FactoryBean源码

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }

xml配置

<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
 <bean id="student" class="com.spring.bean.Student">  
  <property name="name" value="zhangsan" />  
 </bean>  
 
 <bean id="school" class="com.spring.bean.School">  
 </bean> 
 
 <bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo">  
    <property name="type" value="student" />
 </bean> 
</beans>

实现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 + "]";
	}
}

运行

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());
	}
}

运行结果

com.spring.bean.Student
com.spring.bean.FactoryBeanPojo

区别

BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范,

FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节。

一文搞懂BeanFactory和FactoryBean区别

BeanFactory和FactoryBean的区别