通过《spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor》一文了解到了spring对扩展点BeanFactoryPostProcessor是如何处理的,接下来看看spring是如何创建bean的。进入AbstractApplicationContext.refresh方法
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) { 3 prepareRefresh(); 4 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 5 prepareBeanFactory(beanFactory); 6 7 try { 8 postProcessBeanFactory(beanFactory); 9 invokeBeanFactoryPostProcessors(beanFactory); 10 registerBeanPostProcessors(beanFactory); 11 initMessageSource(); 12 initApplicationEventMulticaster(); 13 onRefresh(); 14 registerListeners(); 15 finishBeanFactoryInitialization(beanFactory); 16 finishRefresh(); 17 } 18 19 catch (BeansException ex) { 20 if (logger.isWarnEnabled()) { 21 logger.warn("Exception encountered during context initialization - " + 22 "cancelling refresh attempt: " + ex); 23 } 24 destroyBeans(); 25 cancelRefresh(ex); 26 throw ex; 27 } 28 29 finally { 30 resetCommonCaches(); 31 } 32 } 33 }
spring在创建bean前,会先注册BeanPostProcessor(BeanPostProcessor是spring对外暴露的另一个扩展点,会在spring创建bean前后调用相应的方法,具体参考《Spring探秘|妙用BeanPostProcessor》),然后初始化spring事件传播相关功能。spring bean的创建入口在finishBeanFactoryInitialization方法,spring在容器初始化时,会先初始化lazy-init=false和单例的bean。
1 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { 2 // Initialize conversion service for this context. 3 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && 4 beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { 5 beanFactory.setConversionService( 6 beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); 7 } 8 9 // Register a default embedded value resolver if no bean post-processor 10 // (such as a PropertyPlaceholderConfigurer bean) registered any before: 11 // at this point, primarily for resolution in annotation attribute values. 12 if (!beanFactory.hasEmbeddedValueResolver()) { 13 beanFactory.addEmbeddedValueResolver(new StringValueResolver() { 14 @Override 15 public String resolveStringValue(String strVal) { 16 return getEnvironment().resolvePlaceholders(strVal); 17 } 18 }); 19 } 20 21 // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 22 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); 23 for (String weaverAwareName : weaverAwareNames) { 24 getBean(weaverAwareName); 25 } 26 27 // Stop using the temporary ClassLoader for type matching. 28 beanFactory.setTempClassLoader(null); 29 30 // Allow for caching all bean definition metadata, not expecting further changes. 31 beanFactory.freezeConfiguration(); 32 33 // Instantiate all remaining (non-lazy-init) singletons. 34 beanFactory.preInstantiateSingletons(); 35 }
finishBeanFactoryInitialization方法里首先判断是否有包含conversionService名字的bean,如果有先创建。由于我们在配置bean的属性时,都是以字符串的形式来配置,如下
1 <bean id="test" class="com.zksite.spring.test.SpringBeanTest"> 2 <property name="num" value="1"></property> 3 </bean>
但num的类型不一定是String,有可能是Integer、Boolean、BigDecimal等,conversionService的作用就是将配置的字符串转为实际的类型,关于更多的conversionService的使用可以参考其他网上资料。
接着finishBeanFactoryInitialization方法12行,首先判断beanFactory是否有EmbeddedValueResolver,如果没有,添加一个StringValueResolver。由于DefaultListableBeanFactory实现了ConfigurableBeanFactory,所以当没有EmbeddedValueResolver时调用resolveEmbeddedValue方法是获取环境变量。一般我们项目里都会配置指定的配置文件,那么当配置了指定的配置文件时,可以通过resolveEmbeddedValue("${name}")的形式获取配置文件的内容,更多时候我们会通过@Value注解获取配置文件的内容,当然这需要更多的配置。
接着创建实现了LoadTimeWeaverAware接口的bean(先忽略LoadTimeWeaverAware的内容),然后缓存所有的bean name。beanFactory.preInstantiateSingletons()开始创建所有的单例bean,进入preInstantiateSingletons方法,方法里首先遍历beanNames去创建bean,然后回调实现了SmartInitializingSingleton接口的bean的afterSingletonsInstantiated方法
1 public void preInstantiateSingletons() throws BeansException { 2 if (this.logger.isDebugEnabled()) { 3 this.logger.debug("Pre-instantiating singletons in " + this); 4 } 5 6 // Iterate over a copy to allow for init methods which in turn register new bean definitions. 7 // While this may not be part of the regular factory bootstrap, it does otherwise work fine. 8 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); 9 10 // Trigger initialization of all non-lazy singleton beans... 11 for (String beanName : beanNames) { 12 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 13 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 14 if (isFactoryBean(beanName)) { 15 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); 16 boolean isEagerInit; 17 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 18 isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 19 @Override 20 public Boolean run() { 21 return ((SmartFactoryBean<?>) factory).isEagerInit(); 22 } 23 }, getAccessControlContext()); 24 } 25 else { 26 isEagerInit = (factory instanceof SmartFactoryBean && 27 ((SmartFactoryBean<?>) factory).isEagerInit()); 28 } 29 if (isEagerInit) { 30 getBean(beanName); 31 } 32 } 33 else { 34 getBean(beanName); 35 } 36 } 37 } 38 39 // Trigger post-initialization callback for all applicable beans... 40 for (String beanName : beanNames) { 41 Object singletonInstance = getSingleton(beanName); 42 if (singletonInstance instanceof SmartInitializingSingleton) { 43 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 44 if (System.getSecurityManager() != null) { 45 AccessController.doPrivileged(new PrivilegedAction<Object>() { 46 @Override 47 public Object run() { 48 smartSingleton.afterSingletonsInstantiated(); 49 return null; 50 } 51 }, getAccessControlContext()); 52 } 53 else { 54 smartSingleton.afterSingletonsInstantiated(); 55 } 56 } 57 } 58 }
循环体里首选获取合并的BeanDefinition,为什么需要获取合并后的BeanDefinition呢?其实只有当我们在配置bean时,如果指定了parent属性时,getMergedLocalBeanDefinition方法里会递归获取父级BeanDefinition,然后通过getMergedLocalBeanDefinition返回的RootBeanDefinition判断是否不是抽象的bean并且是单例和非懒加载的,如果这三者都成立,那么再判断是否是一个FactoryBean(FactoryBean是一个特殊的bean,通过beanName获取得到的不是FactoryBean本身,最终返回的bean是通过回调FactoryBean.getObject返回的),接着调用getBean方法,getBean方法是通过调用doGetBean方法,直接进入doGetBean方法
1 protected <T> T doGetBean( 2 final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 3 throws BeansException { 4 5 final String beanName = transformedBeanName(name); 6 Object bean; 7 8 // Eagerly check singleton cache for manually registered singletons. 9 Object sharedInstance = getSingleton(beanName); 10 if (sharedInstance != null && args == null) { 11 if (logger.isDebugEnabled()) { 12 if (isSingletonCurrentlyInCreation(beanName)) { 13 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + 14 "' that is not fully initialized yet - a consequence of a circular reference"); 15 } 16 else { 17 logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); 18 } 19 } 20 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 21 } 22 23 else { 24 // Fail if we're already creating this bean instance: 25 // We're assumably within a circular reference. 26 if (isPrototypeCurrentlyInCreation(beanName)) { 27 throw new BeanCurrentlyInCreationException(beanName); 28 } 29 30 // Check if bean definition exists in this factory. 31 BeanFactory parentBeanFactory = getParentBeanFactory(); 32 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 33 // Not found -> check parent. 34 String nameToLookup = originalBeanName(name); 35 if (args != null) { 36 // Delegation to parent with explicit args. 37 return (T) parentBeanFactory.getBean(nameToLookup, args); 38 } 39 else { 40 // No args -> delegate to standard getBean method. 41 return parentBeanFactory.getBean(nameToLookup, requiredType); 42 } 43 } 44 45 if (!typeCheckOnly) { 46 markBeanAsCreated(beanName); 47 } 48 49 try { 50 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 51 checkMergedBeanDefinition(mbd, beanName, args); 52 53 // Guarantee initialization of beans that the current bean depends on. 54 String[] dependsOn = mbd.getDependsOn(); 55 if (dependsOn != null) { 56 for (String dependsOnBean : dependsOn) { 57 if (isDependent(beanName, dependsOnBean)) { 58 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 59 "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); 60 } 61 registerDependentBean(dependsOnBean, beanName); 62 getBean(dependsOnBean); 63 } 64 } 65 66 // Create bean instance. 67 if (mbd.isSingleton()) { 68 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 69 @Override 70 public Object getObject() throws BeansException { 71 try { 72 return createBean(beanName, mbd, args); 73 } 74 catch (BeansException ex) { 75 // Explicitly remove instance from singleton cache: It might have been put there 76 // eagerly by the creation process, to allow for circular reference resolution. 77 // Also remove any beans that received a temporary reference to the bean. 78 destroySingleton(beanName); 79 throw ex; 80 } 81 } 82 }); 83 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 84 } 85 86 else if (mbd.isPrototype()) { 87 // It's a prototype -> create a new instance. 88 Object prototypeInstance = null; 89 try { 90 beforePrototypeCreation(beanName); 91 prototypeInstance = createBean(beanName, mbd, args); 92 } 93 finally { 94 afterPrototypeCreation(beanName); 95 } 96 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 97 } 98 99 else { 100 String scopeName = mbd.getScope(); 101 final Scope scope = this.scopes.get(scopeName); 102 if (scope == null) { 103 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 104 } 105 try { 106 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 107 @Override 108 public Object getObject() throws BeansException { 109 beforePrototypeCreation(beanName); 110 try { 111 return createBean(beanName, mbd, args); 112 } 113 finally { 114 afterPrototypeCreation(beanName); 115 } 116 } 117 }); 118 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 119 } 120 catch (IllegalStateException ex) { 121 throw new BeanCreationException(beanName, 122 "Scope '" + scopeName + "' is not active for the current thread; consider " + 123 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 124 ex); 125 } 126 } 127 } 128 catch (BeansException ex) { 129 cleanupAfterBeanCreationFailure(beanName); 130 throw ex; 131 } 132 } 133 134 // Check if required type matches the type of the actual bean instance. 135 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { 136 try { 137 return getTypeConverter().convertIfNecessary(bean, requiredType); 138 } 139 catch (TypeMismatchException ex) { 140 if (logger.isDebugEnabled()) { 141 logger.debug("Failed to convert bean '" + name + "' to required type [" + 142 ClassUtils.getQualifiedName(requiredType) + "]", ex); 143 } 144 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 145 } 146 } 147 return (T) bean; 148 }
这个方法有点长,方法里第一步调用transformedBeanName改造bean name,transformedBeanName首先判断name是以“&”开头,如果是去掉,返回真正的bane name,接着判断传入的name是否是别名,bean的创建都是通过bean name去创建,所以通过transformedBeanName方法返回的是最终的bean name。得到bean name之后,首先尝试通过getSingleton方法获取bean,这是为了解决循环依赖,这里先不看是具体怎么解决循环依赖的,后面会提到。如果通过getSingleton方法返回的对象不为空,进去getObjectForBeanInstance()方法,getObjectForBeanInstance处理的主要内容是针对当前的bean是一个FactoryBean,关于FactoryBean先残忍得忽略。
当getSingleton返回的的对象为空时,开始创建bean,如果当前的beanFactory的parentFactory不为空,那么创建bean是会委派给parentFactory去做。创建前会做一些前置检查,分别有判断当前创建的bean是否正在创建,是否是一个抽象bean。当这些检查通过时,首先初始化当前bean依赖的bean。不管是单例的bean还是原型的bean都是通过createBean方法去创建,只不过当是一个单例的bean时,可能在创建前后会做一些其它处理,例如解决循环依赖和将已创建的bean缓存。进入DefaultSingletonBeanRegistry.getSingleton方法,DefaultSingletonBeanRegistry是SingletonBeanRegistry的默认实现,通过类名发现这是一个单例bean的注册中心,SingletonBeanRegistry接口定义了单例bean的注册,和获取单例bean等接口,但真正的创建bean,SingletonBeanRegistry没有定义而是由AbstractBeanFactory定义,实现是AbstractAutowireCapableBeanFactory,我们当前使用的DefaultListableBeanFactory都直接或间接实现了这些接口。
1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { 2 Assert.notNull(beanName, "'beanName' must not be null"); 3 synchronized (this.singletonObjects) { 4 Object singletonObject = this.singletonObjects.get(beanName); 5 if (singletonObject == null) { 6 if (this.singletonsCurrentlyInDestruction) { 7 throw new BeanCreationNotAllowedException(beanName, 8 "Singleton bean creation not allowed while the singletons of this factory are in destruction " + 9 "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); 10 } 11 if (logger.isDebugEnabled()) { 12 logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); 13 } 14 beforeSingletonCreation(beanName); 15 boolean newSingleton = false; 16 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 17 if (recordSuppressedExceptions) { 18 this.suppressedExceptions = new LinkedHashSet<Exception>(); 19 } 20 try { 21 singletonObject = singletonFactory.getObject(); 22 newSingleton = true; 23 } 24 catch (IllegalStateException ex) { 25 // Has the singleton object implicitly appeared in the meantime -> 26 // if yes, proceed with it since the exception indicates that state. 27 singletonObject = this.singletonObjects.get(beanName); 28 if (singletonObject == null) { 29 throw ex; 30 } 31 } 32 catch (BeanCreationException ex) { 33 if (recordSuppressedExceptions) { 34 for (Exception suppressedException : this.suppressedExceptions) { 35 ex.addRelatedCause(suppressedException); 36 } 37 } 38 throw ex; 39 } 40 finally { 41 if (recordSuppressedExceptions) { 42 this.suppressedExceptions = null; 43 } 44 afterSingletonCreation(beanName); 45 } 46 if (newSingleton) { 47 addSingleton(beanName, singletonObject); 48 } 49 } 50 return (singletonObject != NULL_OBJECT ? singletonObject : null); 51 } 52 }
方法里首先从singletonObjects这个Map里面获取,如果当前获取的bean已创建,singletonObjects返回的的值不为空,然后直接返回给上层。当从singletonObjects获取不到指定的值时,这时需要创建一个,创建前调用beforeSingletonCreation,这个方法里有两个作用,分别是判断当前创建的bean是否正在创建和使用一个set将当前创建的bean name保存起来为了解决循环依赖。然后调用singletonFactory.getObject创建bean,当创建bean成功时会删除之前使用set保存的当前创建bean name并将bean缓存在一个map里。singletonFactory.getObject是通过调用AbstractAutowireCapableBeanFactory.createBean创建bean实例,进入createBean方法
1 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { 2 if (logger.isDebugEnabled()) { 3 logger.debug("Creating instance of bean '" + beanName + "'"); 4 } 5 RootBeanDefinition mbdToUse = mbd; 6 7 // Make sure bean class is actually resolved at this point, and 8 // clone the bean definition in case of a dynamically resolved Class 9 // which cannot be stored in the shared merged bean definition. 10 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 11 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 12 mbdToUse = new RootBeanDefinition(mbd); 13 mbdToUse.setBeanClass(resolvedClass); 14 } 15 16 // Prepare method overrides. 17 try { 18 mbdToUse.prepareMethodOverrides(); 19 } 20 catch (BeanDefinitionValidationException ex) { 21 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 22 beanName, "Validation of method overrides failed", ex); 23 } 24 25 try { 26 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 27 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 28 if (bean != null) { 29 return bean; 30 } 31 } 32 catch (Throwable ex) { 33 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 34 "BeanPostProcessor before instantiation of bean failed", ex); 35 } 36 37 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 38 if (logger.isDebugEnabled()) { 39 logger.debug("Finished creating instance of bean '" + beanName + "'"); 40 } 41 return beanInstance; 42 }
方法里首先调用resolveBeanClass方法获取bean的calss,通过查看resolveBeanClass方法,可以发现,bean的class属性可以配置为spl表达式。接着就是校验lookup-method和replaced-method,检查创建的bean是否有指定的方法。当这些准备工作做完时,尝试通过配置的InstantiationAwareBeanPostProcessor去创建实例, 如果存在InstantiationAwareBeanPostProcessor并创建了实例,调用所有的BeanPostProcessor.postProcessAfterInitialization完成bean的创建并返回。如果没有调用doCreateBean执行创建bean实例。
1 BeanWrapper instanceWrapper = null; 2 if (mbd.isSingleton()) { 3 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 4 } 5 if (instanceWrapper == null) { 6 instanceWrapper = createBeanInstance(beanName, mbd, args); 7 }
方法里首先通过缓存获取BeanWrapper实例,spring使用BeanWrapper定义了一个标准javaBean的操作。如果缓存不存在调用createBeanInstance方法创建实例。进入createBeanInstance方法
1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { 2 // Make sure bean class is actually resolved at this point. 3 Class<?> beanClass = resolveBeanClass(mbd, beanName); 4 5 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { 6 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 7 "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); 8 } 9 10 if (mbd.getFactoryMethodName() != null) { 11 return instantiateUsingFactoryMethod(beanName, mbd, args); 12 } 13 14 // Shortcut when re-creating the same bean... 15 boolean resolved = false; 16 boolean autowireNecessary = false; 17 if (args == null) { 18 synchronized (mbd.constructorArgumentLock) { 19 //resolvedConstructorOrFactoryMethod用于缓存构造方法或者factoryMethod 20 //只有当创建的bean是scope=prototype,并且在第二次getBean时resolvedConstructorOrFactoryMethod的值才不会为空 21 if (mbd.resolvedConstructorOrFactoryMethod != null) { 22 resolved = true; 23 //constructorArgumentsResolved用于标识是否解决了构造器法参数 24 autowireNecessary = mbd.constructorArgumentsResolved; 25 } 26 } 27 } 28 if (resolved) { 29 if (autowireNecessary) { 30 return autowireConstructor(beanName, mbd, null, null); 31 } 32 else { 33 return instantiateBean(beanName, mbd); 34 } 35 } 36 37 // Need to determine the constructor... 38 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 39 if (ctors != null || 40 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || 41 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 42 return autowireConstructor(beanName, mbd, ctors, args); 43 } 44 45 // No special handling: simply use no-arg constructor. 46 return instantiateBean(beanName, mbd); 47 }
从实现逻辑可以看出,创建bean实例的有三种方式:工厂方法、自动装配构造器实例化、默认构造器实例化,分别对应不同的方法:
instantiateUsingFactoryMethod:当配置了factory-method属性时
autowireConstructor:当配置了constructor-arg属性时
instantiateBean:使用默认的构造器创建实例
instantiateUsingFactoryMethod方法和autowireConstructor放在创建流程其实差不多,大体流程以下,更详细可以参考源码
1.找出对应的方法或构造器
2.获取方法参数值数组
3.计算参数与值的权重,获取最优构造器或方法。(具体实现挺有意思的)
4.当获取到构造器或方法后,通过CglibSubclassingInstantiationStrategy创建实例,具体和instantiateBean方法一样。
instantiateBean默认构造器实例化
当使用的是默认的构造器实例化时,会使用BeanFactory持有的CglibSubclassingInstantiationStrategy实例去创建实例。如果当前的bean使用了方法注入会使用cglib生生成代理对象并返回。否则直接获取默认的无参构造器,然后通过构造器创建实例并返回。
至此spring已经完成了单例bean的初始化。当bean初始化后,如果当前的bean是一个单例的bean,spring会马上将bean临时缓存起来,用于解决循环依赖,由此可以看出,spring只对视单例的bean提供循环依赖的支持。
1 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 2 isSingletonCurrentlyInCreation(beanName)); 3 if (earlySingletonExposure) { 4 if (logger.isDebugEnabled()) { 5 logger.debug("Eagerly caching bean '" + beanName + 6 "' to allow for resolving potential circular references"); 7 } 8 addSingletonFactory(beanName, new ObjectFactory<Object>() { 9 @Override 10 public Object getObject() throws BeansException { 11 return getEarlyBeanReference(beanName, mbd, bean); 12 } 13 }); 14 }
当解决完循环依赖之后,接着便是属性的注入和回调前后置处理。
1 //属性注入 2 populateBean(beanName, mbd, instanceWrapper); 3 if (exposedObject != null) { 4 //处理回调 5 exposedObject = initializeBean(beanName, exposedObject, mbd); 6 }