原创

Spring源码-BeanFactory和FactoryBean区别

文章源码:https://github.com/Sniper2016/SpringStudy

一、BeanFactory 和 FactoryBean 概念

spring的缔造者Rod Johnson是一个牛逼哄哄的人物,光从spring命名风格,DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext,ApplicationContextAware,InitializingBean等等,我们能大体知道,一个名字最后一个单词表示是什么,前面部分是修饰,表示有啥用。所以 BeanFactory 是一个 IOC 容器或 Bean 对象工厂; FactoryBean 是一个 Bean;

在 Spring 中有两种 Bean,一种是普通 Bean,另一种就是像 FactoryBean 这样的工厂 Bean,无论是那种 Bean,都是由 IOC 容器来管理的。 FactoryBean 可以说为 IOC 容器中 Bean 的实现提供了更加灵活的方式,FactoryBean 在 IOC 容器的基础上给 Bean 的实现,加上了一个简单工厂模式和装饰模式,我们可以在 getObject()方法中灵活配置。

二、BeanFactory 和 FactoryBean 深入源码

1、BeanFactory

BeanFactory 是 IOC 最基本的容器,负责生产和管理 bean,它为其他具体的 IOC 容器提供了最基本的规范,

例如 DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了 BeanFactory,再在其基础之上附加了其他的功能。

BeanFactory 源码:

package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
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;
 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
 boolean containsBean(String name);
 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
 boolean isTypeMatch(String name, Class< > typeToMatch) 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 之前加上&。

FactoryBean 源码:

package org.springframework.beans.factory;
public interface FactoryBean<T> {
 // 返回由FactoryBean创建的Bean的实例
 T getObject() throws Exception;
 // 返回FactoryBean创建的Bean的类型
 Class< > getObjectType();
 // 确定由FactoryBean创建的Bean的作用域是singleton还是prototype
 boolean isSingleton();
}

三、实例分析

方便演示,下文使用注解来演示,免得额外配置xml

CarBean

package cn.gameboys.factory;
public class CarBean {
}

CarFactoryBean

package cn.gameboys.factory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component
public class CarFactoryBean implements FactoryBean<CarBean> {
 @Override
 public CarBean getObject() throws Exception {

  return new CarBean();
 }
 @Override
 public Class<?> getObjectType() {
  return CarBean.class;
 }
 @Override
 public boolean isSingleton() {
  return false;
 }
}

配置类JavaConfig

package cn.gameboys.factory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class JavaConfig {
}



启动类

package cn.gameboys.factory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
 public static void main(String[] args) {
  ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
  // 得到的是carBean
  System.out.println(context.getBean("carFactoryBean"));
  // 得到的是carBean工厂
  System.out.println(context.getBean("&carFactoryBean"));
 }
}

运行结果

cn.gameboys.factory.CarBean@52102734
cn.gameboys.factory.CarFactoryBean@3541cb24

我们可以看到context.getBean("carFactoryBean")生成的bean为CarBean,而非CarFactoryBean。

四、总结

  • Spring框架就是一个bean工厂,或者叫bean容器,有无数的bean配置初始化的时候放进去,使用的时候get一下,他就是围绕着这些bean的生命周期来做文章,只要能理解这一点,其他的都很好理解。
  • BeanFactory是一个IOC基础容器。
  • FactoryBean是一个Bean,不是一个普通Bean,是一个工厂Bean。
  • FactoryBean实现与工厂模式和装饰模式类似。
  • 通过转义符&来区分获取FactoryBean产生的对象和FactoryBean对象本身(FactoryBean实现类)。
正文到此结束