Spring bean 实例化
小洋前面的已经看到了Spring bean的解析了。可是聪明的小洋发现那时候的bean并没有实例化。抱着不到黄河不死心的想法,小洋又开始了艰难的旅程。
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 public void refresh () throws BeansException, IllegalStateException { Object var1 = this .startupShutdownMonitor; synchronized (this .startupShutdownMonitor) { this .prepareRefresh(); ConfigurableListableBeanFactory beanFactory = this .obtainFreshBeanFactory(); this .prepareBeanFactory(beanFactory); try { this .postProcessBeanFactory(beanFactory); this .invokeBeanFactoryPostProcessors(beanFactory); this .registerBeanPostProcessors(beanFactory); this .initMessageSource(); this .initApplicationEventMulticaster(); this .onRefresh(); this .registerListeners(); this .finishBeanFactoryInitialization(beanFactory); this .finishRefresh(); } catch (BeansException var5) { this .logger.warn("Exception encountered during context initialization - cancelling refresh attempt" , var5); this .destroyBeans(); this .cancelRefresh(var5); throw var5; } } }
小洋又回到了开始Spring初始化的时候,获取beanFactory之后还有好多个方法,根据名称其实已经能看出来都干什么的,小洋主要看了finishBeanFactoryInitialization这个方法,是做预实例化bean的,为什么叫预实例化呢。经过小洋一番研究,发现Spring在初始化的时候将配置的bean或者扫描的bean解析成BeanDefinition数据对象,之后并不是将所有解析出来的bean在Spring初始化的就实例化。只有特定条件的bean才会在Spring初始化的时候实例化。什么条件呢?容小洋娓娓道来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 protected void finishBeanFactoryInitialization (ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean("conversionService" ) && beanFactory.isTypeMatch("conversionService" , ConversionService.class )) { beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService" , ConversionService.class )) ; } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class , false , false ) ; String[] var3 = weaverAwareNames; int var4 = weaverAwareNames.length; for (int var5 = 0 ; var5 < var4; ++var5) { String weaverAwareName = var3[var5]; this .getBean(weaverAwareName); } beanFactory.setTempClassLoader((ClassLoader)null ); beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); }
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 66 67 68 69 70 71 72 73 74 75 76 77 public void preInstantiateSingletons () throws BeansException { if (this .logger.isDebugEnabled()) { this .logger.debug("Pre-instantiating singletons in " + this ); } ArrayList beanNames = new ArrayList(this .beanDefinitionNames); Iterator var2 = beanNames.iterator(); while (true ) { while (true ) { String beanName; RootBeanDefinition singletonInstance; do { do { do { if (!var2.hasNext()) { var2 = beanNames.iterator(); while (var2.hasNext()) { beanName = (String)var2.next(); Object singletonInstance1 = this .getSingleton(beanName); if (singletonInstance1 instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton1 = (SmartInitializingSingleton)singletonInstance1; if (System.getSecurityManager() != null ) { AccessController.doPrivileged(new PrivilegedAction() { public Object run () { smartSingleton1.afterSingletonsInstantiated(); return null ; } }, this .getAccessControlContext()); } else { smartSingleton1.afterSingletonsInstantiated(); } } } return ; } beanName = (String)var2.next(); singletonInstance = this .getMergedLocalBeanDefinition(beanName); } while (singletonInstance.isAbstract()); } while (!singletonInstance.isSingleton()); } while (singletonInstance.isLazyInit()); if (this .isFactoryBean(beanName)) { final FactoryBean smartSingleton = (FactoryBean)this .getBean("&" + beanName); boolean isEagerInit; if (System.getSecurityManager() != null && smartSingleton instanceof SmartFactoryBean) { isEagerInit = ((Boolean)AccessController.doPrivileged(new PrivilegedAction() { public Boolean run () { return Boolean.valueOf(((SmartFactoryBean)smartSingleton).isEagerInit()); } }, this .getAccessControlContext())).booleanValue(); } else { isEagerInit = smartSingleton instanceof SmartFactoryBean && ((SmartFactoryBean)smartSingleton).isEagerInit(); } if (isEagerInit) { this .getBean(beanName); } } else { this .getBean(beanName); } } } }
小洋发现在只有是单例模式的并且不是懒加载的bean才会在Spring初始化的实例化。
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 protected <T> T doGetBean (String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = this .transformedBeanName(name); Object sharedInstance = this .getSingleton(beanName); Object bean; if (sharedInstance != null && args == null ) { if (this .logger.isDebugEnabled()) { if (this .isSingletonCurrentlyInCreation(beanName)) { this .logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference" ); } else { this .logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'" ); } } bean = this .getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null ); } else { if (this .isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory ex = this .getParentBeanFactory(); if (ex != null && !this .containsBeanDefinition(beanName)) { String var24 = this .originalBeanName(name); if (args != null ) { return ex.getBean(var24, args); } return ex.getBean(var24, requiredType); } if (!typeCheckOnly) { this .markBeanAsCreated(beanName); } try { final RootBeanDefinition ex1 = this .getMergedLocalBeanDefinition(beanName); this .checkMergedBeanDefinition(ex1, beanName, args); String[] dependsOn = ex1.getDependsOn(); String[] scopeName; if (dependsOn != null ) { scopeName = dependsOn; int scope = dependsOn.length; for (int ex2 = 0 ; ex2 < scope; ++ex2) { String dependsOnBean = scopeName[ex2]; if (this .isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dependsOnBean + "\'" ); } this .registerDependentBean(dependsOnBean, beanName); this .getBean(dependsOnBean); } } if (ex1.isSingleton()) { sharedInstance = this .getSingleton(beanName, new ObjectFactory() { public Object getObject () throws BeansException { try { return AbstractBeanFactory.this .createBean(beanName, ex1, args); } catch (BeansException var2) { AbstractBeanFactory.this .destroySingleton(beanName); throw var2; } } }); bean = this .getObjectForBeanInstance(sharedInstance, name, beanName, ex1); } else if (ex1.isPrototype()) { scopeName = null ; Object var25; try { this .beforePrototypeCreation(beanName); var25 = this .createBean(beanName, ex1, args); } finally { this .afterPrototypeCreation(beanName); } bean = this .getObjectForBeanInstance(var25, name, beanName, ex1); } else { String var26 = ex1.getScope(); Scope var27 = (Scope)this .scopes.get(var26); if (var27 == null ) { throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'" ); } try { Object var28 = var27.get(beanName, new ObjectFactory() { public Object getObject () throws BeansException { AbstractBeanFactory.this .beforePrototypeCreation(beanName); Object var1; try { var1 = AbstractBeanFactory.this .createBean(beanName, ex1, args); } finally { AbstractBeanFactory.this .afterPrototypeCreation(beanName); } return var1; } }); bean = this .getObjectForBeanInstance(var28, name, beanName, ex1); } catch (IllegalStateException var21) { throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton" , var21); } } } catch (BeansException var23) { this .cleanupAfterBeanCreationFailure(beanName); throw var23; } } return bean; }
创建bean调用的核心方法都一样,只是区分了isSingleton或isPrototype或者其他的。对于singleton的会放在缓存里面,下次直接获取。而prototype则没有放入缓存。下面看创建bean的方法。
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 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, Object[] args) { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = this .createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper != null ?instanceWrapper.getWrappedInstance():null ; Object exposedObject = bean; try { this .populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null ) { exposedObject = this .initializeBean(beanName, exposedObject, mbd); } } catch (Throwable var17) { if (var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) { throw (BeanCreationException)var17; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed" , var17); } }
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 protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, Object[] args) { Class beanClass = this .resolveBeanClass(mbd, beanName, new Class[0 ]); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn\'t public, and non-public access not allowed: " + beanClass.getName()); } else if (mbd.getFactoryMethodName() != null ) { return this .instantiateUsingFactoryMethod(beanName, mbd, args); } else { boolean resolved = false ; boolean autowireNecessary = false ; if (args == null ) { Object ctors = mbd.constructorArgumentLock; synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null ) { resolved = true ; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { return autowireNecessary?this .autowireConstructor(beanName, mbd, (Constructor[])null , (Object[])null ):this .instantiateBean(beanName, mbd); } else { Constructor[] ctors1 = this .determineConstructorsFromBeanPostProcessors(beanClass, beanName); return ctors1 == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this .instantiateBean(beanName, mbd):this .autowireConstructor(beanName, mbd, ctors1, args); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public Class<?> resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException { String className = this .getBeanClassName(); if (className == null ) { return null ; } else { Class resolvedClass = ClassUtils.forName(className, classLoader); this .beanClass = resolvedClass; return resolvedClass; } }
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 public Object instantiate (RootBeanDefinition bd, String beanName, BeanFactory owner) { if (bd.getMethodOverrides().isEmpty()) { Object var5 = bd.constructorArgumentLock; Constructor constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null ) { final Class clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface" ); } try { if (System.getSecurityManager() != null ) { constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction() { public Constructor<?> run() throws Exception { return clazz.getDeclaredConstructor((Class[])null ); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[])null ); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception var9) { throw new BeanInstantiationException(clazz, "No default constructor found" , var9); } } } return BeanUtils.instantiateClass(constructorToUse, new Object[0 ]); } else { return this .instantiateWithMethodInjection(bd, beanName, owner); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static <T> T instantiateClass (Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null" ); try { ReflectionUtils.makeAccessible(ctor); return ctor.newInstance(args); } catch (InstantiationException var3) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?" , var3); } catch (IllegalAccessException var4) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?" , var4); } catch (IllegalArgumentException var5) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor" , var5); } catch (InvocationTargetException var6) { throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception" , var6.getTargetException()); } }
看到这里已经看到了bean的实例化了。其实就是通过反射获取构造方法然后执行newInstance来实例化的。实例化就该干什么呢,属性注入了。
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 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, Object[] args) { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = this .createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper != null ?instanceWrapper.getWrappedInstance():null ; Class beanType = instanceWrapper != null ?instanceWrapper.getWrappedClass():null ; Object earlySingletonExposure = mbd.postProcessingLock; synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { this .applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true ; } } Object exposedObject = bean; try { this .populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null ) { exposedObject = this .initializeBean(beanName, exposedObject, mbd); } } catch (Throwable var17) { if (var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) { throw (BeanCreationException)var17; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed" , var17); } }
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 protected void populateBean (String beanName, RootBeanDefinition mbd, BeanWrapper bw) { Object pvs = mbd.getPropertyValues(); if (bw == null ) { if (!((PropertyValues)pvs).isEmpty()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance" ); } } else { boolean hasInstAwareBpps2 = this .hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck1 = mbd.getDependencyCheck() != 0 ; if (hasInstAwareBpps2 || needsDepCheck1) { PropertyDescriptor[] filteredPds1 = this .filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps2) { Iterator var9 = this .getBeanPostProcessors().iterator(); while (var9.hasNext()) { BeanPostProcessor bp = (BeanPostProcessor)var9.next(); if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds1, bw.getWrappedInstance(), beanName); if (pvs == null ) { return ; } } } } if (needsDepCheck1) { this .checkDependencies(beanName, mbd, filteredPds1, (PropertyValues)pvs); } } this .applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { InjectionMetadata metadata = this .findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); return pvs; } catch (Throwable var7) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed" , var7); } }
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 protected void inject (Object target, String requestingBeanName, PropertyValues pvs) throws Throwable { if (this .isField) { Field ex = (Field)this .member; ReflectionUtils.makeAccessible(ex); ex.set(target, this .getResourceToInject(target, requestingBeanName)); } else { if (this .checkPropertySkipping(pvs)) { return ; } try { Method ex1 = (Method)this .member; ReflectionUtils.makeAccessible(ex1); ex1.invoke(target, new Object[]{this .getResourceToInject(target, requestingBeanName)}); } catch (InvocationTargetException var5) { throw var5.getTargetException(); } } }
上面我们看了AutowiredAnnotationBeanPostProcessor的处理属性注入,其实其他的BeanPostProcessor处理都一样,都首先找到自己处理的注解的信息,构造成InjectionMetadata对象去处理。不同的地方就是查找注解的地方。注解的属性注入处理完了,对于xml文件配置bean属性的注入,小洋大概看了下,最后也是通过反射执行set方法初始化的。而且只有反射执行方法,所以xml配置的bean属性注入,必须有对应的set方法。不然会报错的。
小洋的这一番折腾,大概了解了Spring初始化的时候对bean的解析、实例化、属性注入等流程。虽然不是特别的详细,但是具体的流程还是走通的,期间收获不小。