Spring源码解析FactoryBean
【摘要】 FactoryBean是怎么让Spring容器管理调用它的getObject所生成的Bean的。 从getBean方法开始说起。 场景:
beanName:factoryBeanLearnClass类型:FactoryBeanService.class
getBean(beanName, requiredType, args)方法,这个方法又调用doGetBea。 ...
FactoryBean是怎么让Spring容器管理调用它的getObject所生成的Bean的。
从getBean方法开始说起。
场景:
- beanName:factoryBeanLearn
- Class类型:FactoryBeanService.class
getBean(beanName, requiredType, args)方法,这个方法又调用doGetBea。
只关注和FactoryBean相关的内容。
getBean(beanName, requiredType, args)
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { return doGetBean(name, requiredType, args, false);
}
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 转换传入的BeanName,如&name变为name 以及别名(alias)的转换 final String beanName = transformedBeanName(name); Object bean; // 调用getSingleton 从Spring容器获取单例Bean // 这里的beanName为factoryBeanLearn // beanName为factoryBeanLearn的Bean 已经在Spring容器中创建过了(创建过程见AbstractApplicationContext#refresh方法) // 所以这里会获取到一个FactoryBeanLearn实例 // 这里根据beanName获取bean实例的方法 beanName都是经过处理之后的beanName Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // 从实例自身获取对象 像这个实例是一个FactoryBean类型的实例 // 这个方法中传入了一个name 又传入了一个beanName bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
getSingleton从Spring容器中获取单例Bean
返回给定名字注册的(原始)的singleton对象。
检查已经实例化的单例并且还允许的早期引用到当前正在创建的单例(解决循环引用问题)。
- beanName - 寻找的bean名字
- allowEarlyReference - 早期的引用是否建立
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从singletonObjects中获取单例Bean
Object singletonObject = this.singletonObjects.get(beanName);
// 没获取到,则判断是否为当前正在创建中的单例Bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 加锁 synchronized (this.singletonObjects) { // 提前暴露创建的Bean中是否存在beanName的单例Bean singletonObject = this.earlySingletonObjects.get(beanName); // 如果没有获取到 并且允许提前引用响应的Bean if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 从ObjectFactory获取Bean实例 singletonObject = singletonFactory.getObject(); //放入earlySingletonObjects this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } }
}
return singletonObject;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
getObjectForBeanInstance
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 这里判断 name是不是以&开头,不是经过处理的beanName 并且这个bean实例 不是FactoryBean类型的
// 如果Bean不是工厂,则不要让调用代码尝试取消引用工厂。
if (BeanFactoryUtils.isFactoryDereference(name)) { //不是FactoryBean类型 或者name以&开头 直接返回bean实例 //想一下我们关于FactoryBean的知识:如果要根据beanName获取真正的FactoryBean实例的时候 //需要在beanName前面加上& 这里就可以看到为什么要这样做了。 if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { // 如果&开头,但却不是FactoryBean,则抛异常 throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance;
} // 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)) { return beanInstance;
} Object object = null;
if (mbd != null) { mbd.isFactoryBean = true;
}
else { // factoryBeanObjectCache 看看是不是在缓存中 object = getCachedObjectForFactoryBean(beanName);
}
// 如果没有
if (object == null) { // 走到这来,这个bean实例就是FactoryBean类型 // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); // 从FactoryBean中获取对象 object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
getObjectFromFactoryBean的分析
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// FactoryBean实例,调用isSingleton返回true
// 所传入bean实例也要求单例类型
// 对应这里就是FactoryBeanLearn中的方法返回true
if (factory.isSingleton() && containsSingleton(beanName)) { // 加锁 synchronized (getSingletonMutex()) { // 再从缓存中获取一次 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 调用doGetObjectFromFactoryBean从FactoryBean获取bean对象 // 调用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); // 如果刚才缓存中获取到,则用缓存中的替代从FactoryBean中获取的bean 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 { // 调用BeanPostProcessor的postProcessAfterInitialization处理 // 这里只调用BeanPostProcessor的postProcessAfterInitialization 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)) { //放入到factoryBeanObjectCache缓存,key为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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
doGetObjectFromFactoryBean的分析
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { // 调用FactoryBean#getObject()获取bean object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 调用FactoryBean中的getObject()方法获取bean object = factory.getObject(); }
}
catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
} // Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } object = new NullBean();
}
return object;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
流程:
循环Spring容器中所有的beanNames
再根据beanName获取对应的Bean实例
判断获取的Bean实例是不是FactoryBean类型的Bean
- 如果是,则调用Bean的getObjectType方法获取Class,将获取到的Class和传入的Class进行匹配,如果匹配到,则将此beanName和传入的Class建立一个映射关系
再根据beanName获取到Spring容器中对应的Bean,调用Bean的getObject方法来获取对应的实例。
文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。
原文链接:javaedge.blog.csdn.net/article/details/107478245
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)