正如前面所述,在IoC容器的初始化过程中,主要的工作是对BeanDefinition的定位、载入、解析和注册。
此时依赖注入并没有发生,依赖注入发生在应用第一次向容器索要Bean时。向容器索要Bean是通过getBean的
调用来完成的,该getBean是容器提供Bean服务的最基本的接口。
也有一种例外情况,就是用户可以通过设置Bean的lazy-init属性来控制该过程。这种方式会对容器初加载的
性能有一些影响,但却能够提高应用第一次取得Bean的性能。因为应用在第一次取得Bean时,依赖注入已经
结束了,应用可以取得已有的Bean。
在AbstractApplicationContext的refresh方法中
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) { 3 // Prepare this context for refreshing. 4 prepareRefresh(); 5 6 // Tell the subclass to refresh the internal bean factory. 7 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 8 9 // Prepare the bean factory for use in this context. 10 prepareBeanFactory(beanFactory); 11 12 try { 13 // Allows post-processing of the bean factory in context subclasses. 14 postProcessBeanFactory(beanFactory); 15 16 // Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); 18 19 // Register bean processors that intercept bean creation. 20 registerBeanPostProcessors(beanFactory); 21 22 // Initialize message source for this context. 23 initMessageSource(); 24 25 // Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); 27 28 // Initialize other special beans in specific context subclasses. 29 onRefresh(); 30 31 // Check for listener beans and register them. 32 registerListeners(); 33 34 // Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); 36 37 // Last step: publish corresponding event. 38 finishRefresh(); 39 } 40 41 catch (BeansException ex) { 42 if (logger.isWarnEnabled()) { 43 logger.warn("Exception encountered during context initialization - " + 44 "cancelling refresh attempt: " + ex); 45 } 46 47 // Destroy already created singletons to avoid dangling resources. 48 destroyBeans(); 49 50 // Reset 'active' flag. 51 cancelRefresh(ex); 52 53 // Propagate exception to caller. 54 throw ex; 55 } 56 } 57 }
在finishBeanFactoryInitialization的方法中,封装了对lazy-init属性的处理
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 // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 10 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); 11 for (String weaverAwareName : weaverAwareNames) { 12 getBean(weaverAwareName); 13 } 14 15 // Stop using the temporary ClassLoader for type matching. 16 beanFactory.setTempClassLoader(null); 17 18 // Allow for caching all bean definition metadata, not expecting further changes. 19 beanFactory.freezeConfiguration(); 20 21 // Instantiate all remaining (non-lazy-init) singletons. 22 beanFactory.preInstantiateSingletons(); 23 }
实际的处理是在DefaultListableBeanFactory的preInstantiateSingletons方法中完成的
1 public void preInstantiateSingletons() throws BeansException { 2 if (this.logger.isInfoEnabled()) { 3 this.logger.info("Pre-instantiating singletons in " + this); 4 } 5 6 List<String> beanNames; 7 synchronized (this.beanDefinitionMap) { 8 // Iterate over a copy to allow for init methods which in turn register new bean definitions. 9 // While this may not be part of the regular factory bootstrap, it does otherwise work fine. 10 beanNames = new ArrayList<String>(this.beanDefinitionNames); 11 } 12 13 // Trigger initialization of all non-lazy singleton beans... 14 for (String beanName : beanNames) { 15 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 16 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 17 if (isFactoryBean(beanName)) { 18 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); 19 boolean isEagerInit; 20 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 21 isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 22 public Boolean run() { 23 return ((SmartFactoryBean<?>) factory).isEagerInit(); 24 } 25 }, getAccessControlContext()); 26 } 27 else { 28 isEagerInit = (factory instanceof SmartFactoryBean && 29 ((SmartFactoryBean<?>) factory).isEagerInit()); 30 } 31 if (isEagerInit) { 32 getBean(beanName); 33 } 34 } 35 else { 36 getBean(beanName); 37 } 38 } 39 } 40 }
判断 lazy-init为false 进行处理,不设置默认为true