让你真正的理解BeanFactory 与 FactoryBean的区别

文章目录

  • 1.BeanFactory
    • 1.1.概念
    • 1.2.源码
  • 2.FactoryBean
    • 2.1.概念
    • 2.2.源码
  • 3.BeanFactory与FactoryBean的区别
  • 4.FactoryBean实现案例:SqlSessionFactoryBean
    • 4.1.重要代码片段
    • 4.2.源码解读

1.BeanFactory

1.1.概念

1.BeanFactory本质上不是Bean,它是加载Bean的工厂;  
2.BeanFactory从字面意义上看,是以Factory结尾的,所以我们理解为“Bean的一个工厂类”
3.作用:工厂类的行为和功能做了一个定义
	BeanFactory是Spring Bean工厂的顶级工厂接口,其他的工厂类都是实现该类,根据具体的需求做扩展
  	因此,可以认为BeanFactory只是对工厂类的行为和功能做了一个定义;  

1.2.源码


package org.springframework.beans.factory;

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

/*
 * BeanFactory 接口是 Spring 框架中的核 心接口,它是工厂模式的具体实现。
 * BeanFactory 使用控制反转对应用程序的配置和依赖性规范与实际 的应用程序代码进行了分离。
 * 但 BeanFactory 容器实例化后并不会自动实例化 Bean,只有当 Bean 被 使用时 BeanFactory 容器才会对该Bean 进行实例化与依赖关系的装配。
 *
 */
public interface BeanFactory {
	//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
	//如果需要得到工厂本身,需要转义
	String FACTORY_BEAN_PREFIX = "&";

	//根据bean的名字,获取在IOC容器中得到bean实例
	Object getBean(String name) throws BeansException;

	//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
	<T> T getBean(String name, @Nullable 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;

	//提供对bean的检索,看看是否在IOC容器有这个名字的bean
	boolean containsBean(String name);

	//根据bean名字得到bean实例,并同时判断这个bean是不是单例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	//得到bean实例的Class类型
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
	String[] getAliases(String name);

}

2.FactoryBean

2.1.概念

1.FactoryBean本质上它是IOC容器中的一个Bean;
2.FactoryBean在此基础上还有另外一个功能:能够作为Bean的工厂,来产生一个Bean对象;
3.作用是:产生其他bean实例。
  通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。
  由工厂bean产生的其他bean实例,不再由Spring容器产生,因此与普通 bean的配置不同,不再需要提供class元素。

2.2.源码

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

/**
 * FactoryBean是Spring内部实现的一种规范用&开头作为BeanName
 * Spring中所有的容器都是FactoryBean
 * 因为容器本身由容器管理,root来创建
 *
 */
//工厂Bean,用于产生其他对象
public interface FactoryBean<T> {

	
	//获取容器管理的对象实例
	@Nullable
	T getObject() throws Exception;

	//获取Bean工厂创建的对象的类型
	@Nullable
	Class<?> getObjectType();

	//Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例
	//对象,每次请求都返回同一个实例对象
	default boolean isSingleton() {
		return true;
	}

}

3.BeanFactory与FactoryBean的区别

4.FactoryBean实现案例:SqlSessionFactoryBean

4.1.重要代码片段

package org.mybatis.spring;

/**
 * 我们这里SqlSessionFactoryBean 理解为主要是为了生成SqlSessionFactory对象实例的即可 方法:buildSqlSessionFactory()
 */
public class SqlSessionFactoryBean
    implements
  //主要是实现其getObject方法
    FactoryBean<SqlSessionFactory>,
  //主要是实现了afterPropertiesSet方法
    InitializingBean,
    ApplicationListener<ApplicationEvent> {

  private SqlSessionFactory sqlSessionFactory;

  /**
   * 这里主要是是加载mybatis的相关配置
   */
  @Override
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
        "Property 'configuration' and 'configLocation' can not specified with together");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }

  /**
   * 配置样例
   *   
   *         
   *         
   *         
   *   
   */
  protected SqlSessionFactory buildSqlSessionFactory() throws Exception {

	。。。。。。
    return this.sqlSessionFactoryBuilder.build(targetConfiguration);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }
    return this.sqlSessionFactory;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Class<? extends SqlSessionFactory> getObjectType() {
    return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isSingleton() {
    return true;
  }
}

4.2.源码解读

1.首先SqlSessionFactoryBean 实现了FactoryBean接口(其中的方法有:getObject(),getObjectType(), isSingleton)
2.通过调用getObject(),会返回sqlSessionFactory对象;

让你真正的理解BeanFactory 与 FactoryBean的区别_第1张图片

你可能感兴趣的:(spring-source,面试)