Spring源码分析之Bean的创建过程详解

在IOC中,是如何通过beanDefition创建出一个bean的?

各BeanPostProcessor在这过程中扮演的角色,调用时机?

话不多说,直接正题走起,上图!

下面是bean创建过程的大致流程图,本文将以图中顺序进行逐步源码分析,小伙伴亦可与图中流程边对照边品食

原矢量图地址:https://www.processon.com/view/link/5f6174431e08531edf3134fb

img

我们知道,在Spring IOC前段部分有注册了一系列的BeanPostProcessor,在Bean的创建过程中,就将要使用到他们了,下面我给大家一一列出

AutowiredAnnotationBeanPostProcessor:在new AnnotatedBeanDefinitionReader时注册

CommonAnnotationBeanPostProcessor: 在new AnnotatedBeanDefinitionReader时注册

ApplicationContextAwareProcessor: 在prepareBeanFactory时注册

ApplicationListenerDetector: 在prepareBeanFactory时注册

ImportAwareBeanPostProcessor: 在配置类后置处理器调用postProcessBeanFactory注册

BeanPostProcessorChecker:在registerBeanPostProcessors时注册

以上就是Spring中内置的所有BeanPostProcessor了

同样,我们先从最开始的入口refresh开始分析

public void refresh(){ //....省略前面部分 // 实例化剩余的单例bean finishBeanFactoryInitialization(beanFactory); } finishBeanFactoryInitialization protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){ // 将所有非懒加载的bean加载到容器中 beanFactory.preInstantiateSingletons(); }

循环我们之前注册的所有beanDefinition,一个个的进行调用getBean注册到容器中

public void preInstantiateSingletons(){ // 循环所有beanDefinition for (String beanName : beanNames) { // 将beanDefinition转化为RootBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 不是抽象类并且是单例并且非懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 是否为工厂bean if (isFactoryBean(beanName)) { // 由于是以&开头获取bean,这里返回的是一个工厂bean,并且不会调用getObject方法 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { // 判断是否要立即初始化bean FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); if (isEagerInit) { // 以为&开头的方式再获取一次,此时会调用FactoryBean的getObject()方法 getBean(beanName); } } } else { // 不是FactoryBean,直接使用getBean进行初始化 getBean(beanName); } } } }

接下来就是Spring的常规操作,调用do开头的doGetBean

public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }

以下为doGetBean中获取单例bean的逻辑

// 转化beanName 如果是以&开头则去除,如果有别名则获取别名 String beanName = transformedBeanName(name); // 尝试从三级缓存中获取bean Object sharedInstance = getSingleton(beanName); // 是否从缓存中获取到了bean if (sharedInstance != null && args == null) { // 如果是工厂类且name不以&开头,则调用工厂类的getObject() // 其他情况返回原对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } getSingleton public Object getSingleton(String beanName) { return getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从单例缓存池中获取 Object singletonObject = this.singletonObjects.get(beanName); // 获取不到,判断bean是否正在创建 // 如果是正在创建,2种情况 1.多个线程在创建bean 2.发生循环依赖 // 如果是多个线程,则由于同步锁阻塞于此 // 循环依赖的问题较为复杂,将在下章详细分析 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 从早期对象缓存池中获取 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 从三级缓存中获取单例工厂 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 调用回调方法获取早期bean singletonObject = singletonFactory.getObject(); // 将早期对象放到二级缓存,移除三级缓存 this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } getObjectForBeanInstance protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 判断name是否以&开头,是则直接返回该FactoryBean /*public static boolean isFactoryDereference(@Nullable String name) { return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); }*/ if (BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } // 不是工厂bean直接返回原对象 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } // 尝试从缓存中获取,保证多次从工厂bean获取的bean是同一个bean object = getCachedObjectForFactoryBean(beanName); if (object == null) { FactoryBean<?> factory = (FactoryBean<?>) beanInstance; boolean synthetic = (mbd != null && mbd.isSynthetic()); // 从FactoryBean获取对象 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgxxy.html