zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Apache-Shiro分布式环境配置(与redis集成)(转)
    springboot整合mybatis将sql打印到日志(转)
    springboot中logback打印日志(转)
    Spring Boot Junit单元测试
    玩转Spring Boot 自定义配置、导入XML配置与外部化配置
    Windows开机自启动位置
    木马开机启动的六种方法(记录)
    用Delphi开发视频聊天软件
    Delphi用Socket API实现路由追踪
    前端工程师应该都了解的16个最受欢迎的CSS框架
  • 原文地址:https://www.cnblogs.com/toUpdating/p/9728195.html
Copyright © 2011-2022 走看看