Spring中的BeanFactory与FactoryBean

BeanFactory 与 FactoryBean 是spring中长得比较相像的两个接口。
BeanFactory的源码如下:

public interface BeanFactory {  
    /**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans created by the FactoryBean. For example, if the bean named
	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
	 * will return the factory, not the instance returned by the factory.
	 */
    String FACTORY_BEAN_PREFIX = "&"; 
    
    //获取bean的方法:
    Object getBean(String name) throws BeansException;      
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;                 Object getBean(String name, Object... args) throws BeansException;     
    <T> T getBean(Class<T> requiredType) throws BeansException;      
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    
    //获取provider
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);     
    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); 
    
    //是否包含名为name的bean
    boolean containsBean(String name);  
    
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;                   boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;     
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;     
    @Nullable      
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;     
    String[] getAliases(String name);
}

FactoryBean的源码:

public interface FactoryBean<T> {

	//返回该工厂管理的bean实例
	@Nullable
	T getObject() throws Exception;
	
	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}

}

从两个接口的定义上,可以清楚的看出,BeanFactory是用来产生bean的factory类;而FactoryBean是类型为factory的bean。spring中的bean一般可以分为两类:

  • 普通的bean
  • 工厂bean

工厂bean既是被spring管理的bean,也是管理别的bean的工厂bean。(这里有点像spring是一个老师,老师管理所有的学生,但是学生分为了两类,一类就是普通学生,另一个是协助老师管理班级的班干部)。

有一点需要强调的是:如果通过BeanFactory创建FactoryBean,在获取这些FactoryBean的时候,需要在bean的名称前加上前缀“&”符号。

applicationContext.getBean("book")//这样获得的bean是普通的bean
applicationContext.getBean("&book")//这样获得的bean是工厂bean

你可能感兴趣的:(spring)