spring IoC (三)lazy-init

  正如前面所述,在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

posted on 2018-09-30 10:05  持续在更新  阅读(515)  评论(0编辑  收藏  举报

导航