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

xiaoxiao2021-02-28  115

本章内容:

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的构造。


大致流程

转载请注明原文地址: https://www.6miu.com/read-36392.html

最新回复(0)