BeanFactory,这是Spring容器的基础实现类,它负责生产和管理Bean的一个工厂。当然BeanFactory只是一个接口,它的常用实现有XmlBeanFactory、DefaultListableBeanFactory、ApplicationContext等。

FactoryBean

FactoryBean是一个接口

public interface FactoryBean<T> {

    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();
}

Spring官方文档有关FactoryBean解释:If you have complex initialization code that is better expressed in Java as opposed to a (potentially) verbose amount of XML, you can create your own FactoryBean, write the complex initialization inside that class, and then plug your custom FactoryBean into the container.

org.springframework.beans.factory.support.DefaultListableBeanFactory

@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
} // Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { /**
* 判断该bean是否实现FactoryBean接口
* 若需要FactoryBean提前初始化,根据提示可以实现 SmartFactoryBean的isEagerInit的方法
* 若返回true则会在初始化的时候调用getbean方法,在getbean方法中调用对象的getObject方法
*/
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
} // Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
//doGetBean方法最终会调到org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory.
/**
* (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX))
* 判断beanName是否以&开头
*/
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
} // Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
} Object object = null;
if (mbd == null) {
//首先尝试从factoryBeanObjectCache缓存中获取
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
//获取描述FactoryBean的BeanDefinition对象
mbd = getMergedLocalBeanDefinition(beanName);
}
//这个判断可以引出一个知识点,暂时还没理解
boolean synthetic = (mbd != null && mbd.isSynthetic());
//对象在这个方法中获取到
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
//org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//具体在这方法中调用FactoryBean中的GetObject方法
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
//默认不做任何事情,但是它的子类org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory重写了该方法
/* protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
*/
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}

3.总结FactoryBean和BeanFactory

BeanFactory:工厂类接口,Spring容器的核心接口,实例化bean、配置bean之间的依赖关系

FactoryBean:实例化bean过程比较复杂时可以考虑使用

BeanFactory and FactoryBean的更多相关文章

  1. BeanFactory和FactoryBean

    BeanFactory和FactoryBean 1.BeanFactory BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是Spring I ...

  2. Difference between BeanFactory and FactoryBean in Spring Framework (Spring BeanFactory与Factory区别)

    参见原文:http://www.geekabyte.io/2014/11/difference-between-beanfactory-and.html geekAbyte Codes and Ran ...

  3. BeanFactory和FactoryBean的区别

    转自:http://blog.csdn.net/wangbiao007/article/details/53183764 1.BeanFactory BeanFactory是IOC最基本的容器,负责生 ...

  4. Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...

  5. Spring中BeanFactory与FactoryBean的区别

    在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层 ...

  6. Spring BeanFactory 与 FactoryBean 的区别

    BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...

  7. BeanFactory 和FactoryBean的区别

    转自:https://www.cnblogs.com/aspirant/p/9082858.html BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是 ...

  8. Spring的BeanFactory和FactoryBean

    官方定义 BeanFactory:Spring Bean容器的根接口 FactoryBean:各个对象的工厂接口,如果bean实现了这个接口,它将被用作对象的工厂,而不是直接作为bean实例. 源码解 ...

  9. 一文读懂BeanFactory和FactoryBean区别

    一直以来,很多人对于Spring中的BeanFactory和FactoryBean都是分不清楚的 BeanFactory 这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一 ...

  10. spring:Beanfactory和ApplicationContext、BeanFactory 和 FactoryBean

    1.Beanfactory和ApplicationContext有什么区别 ApplicationContext (1)在配置文件加载后创建bean 利用debug方式,在Student类的无参构造方 ...

随机推荐

  1. go xpath

    package main import ( "fmt" "github.com/antchfx/htmlquery" "net/http" ...

  2. Kubernetes K8S之存储Volume详解

    K8S之存储Volume概述与说明,并详解常用Volume示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

  3. CPU 底层运算之乘法运算

    CPU 运算加减法运算 假设计算  3+3  原码是0011 * 0011(以4位存贮单元,因为是原码,最高位不代表符号位) 1. 首先 判断 两个加数是否有 负数(减法)  如果有 负数 先将负数转 ...

  4. Prometheus入门教程(三):Grafana 图表配置快速入门

    文章首发于[陈树义]公众号,点击跳转到原文:https://mp.weixin.qq.com/s/sA0nYevO8yz6QLRz03qJSw 前面我们使用 Prometheus + Grafana ...

  5. django—视图相关

    FBV与CBV FBV:function based view   基于函数的视图 CBV:class based view  基于类的视图 CBV的定义: from django.views imp ...

  6. 用python写一个豆瓣短评通用爬虫(登录、爬取、可视化)

    原创技术公众号:bigsai,本文在1024发布,祝大家节日快乐,心想事成. @ 目录 前言 登录 爬取 储存 可视化分析 前言 在本人上的一门课中,老师对每个小组有个任务要求,介绍和完成一个小模块. ...

  7. 今天 1024,为了不 996,Lombok 用起来以及避坑指南

    Lombok简介.使用.工作原理.优缺点 Lombok 项目是一个 Java 库,它会自动插入编辑器和构建工具中,Lombok 提供了一组有用的注解,用来消除 Java 类中的大量样板代码. 目录 L ...

  8. Vue3实战系列:Vue3.0 + Vant3.0 搭建种子项目

    最近在用 Vue3 写一个开源的商城项目,开源后让大家也可以用现成的 Vue3 大型商城项目源码来练练手,目前处于开发阶段,过程中用到了 Vant3.0,于是就整理了这篇文章来讲一下如何使用 Vue3 ...

  9. 如何利用go-zero在Go中快速实现JWT认证

    关于JWT是什么,大家可以看看官网,一句话介绍下:是可以实现服务器无状态的鉴权认证方案,也是目前最流行的跨域认证解决方案. 要实现JWT认证,我们需要分成如下两个步骤 客户端获取JWT token. ...

  10. this.getResolve is not a function VUE中使用sass

    1. 安装以下依赖 npm install node-sass --save-dev //安装node-sass npm install sass-loader --save-dev //安装sass ...