您的位置:首页 > 编程语言 > Java开发

【简记】Java Web 内幕——Spring中Bean的创建(源码摘录)

2017-07-10 18:23 519 查看
本章内容:

Bean的创建

构建Bean的关系网

http://www.cnblogs.com/xrq730/p/6361578.html

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();

//实例化non-lazy-init 类型的bean
beanFactory.preInstantiateSingletons();
}


public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.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<String>(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()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}


这里先解释一下getMergedLocalBeanDefinition方法的含义,因为这个方法会常常看到。Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。

解释完了getMergedLocalBeanDefinition方法的作用,第1行~第10行的代码就没什么好说的了,根据beanName拿到RootBeanDefinition而已。由于此方法实例化的是所有非懒加载的单例Bean,因此要实例化Bean,必须满足11行的三个定义:

(1)不是抽象的

(2)必须是单例的

(3)必须是非懒加载的

接着简单看一下第12行~第29行的代码,这段代码主要做的是一件事情:首先判断一下Bean是否FactoryBean的实现,接着判断Bean是否SmartFactoryBean的实现,假如Bean是SmartFactoryBean的实现并且eagerInit(这个单词字面意思是渴望加载,找不到一个好的词语去翻译,意思就是定义了这个Bean需要立即加载的意思)的话,会立即实例化这个Bean。

这里出现了一个非常重要的Bean一Factory Bean ,可以说Spring 有一大半的扩展功能都与这个Bean 有关,这是个特殊的Bean 。它是个工厂Bean ,可以产生Bean的Bean ,这里的产生Bean 是指Bean 的实例,如果一个类继FactoryBean ,用户可以自己定义产生实例对象的方法,只需实现它的getObject 方法即可。然而在Spring 内部,这个Bean的实例对象是FactoryBean ,通过调用这个对象的getObject 方法就能获取用户自定义产生的对象,从而为Spring 提供了很好的扩展性。

以下是结合getBean方法的流程图:



createBeanInstance方法

创建出Bean的实例,并包装为BeanWrapper。BeanWrapper的作用,实现了设置和获取属性值的功能。

通过反射生成Bean的实例。看到前面有一步makeAccessible,意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造。

大致流程

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐