返回介绍

6.7 初始化非延迟加载单例

发布于 2025-04-22 22:09:13 字数 5095 浏览 0 评论 0 收藏

完成 BeanFactory 的初始化工作,其中包括 ConversionService 的设置、配置冻结以及非延迟加载的 bean 的初始化工作。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

  // Initialize conversion service for this context.

  if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&

  beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME,

  ConversionService.class)) {

 beanFactory.setConversionService(

  beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME,

  ConversionService.class));

 }

  // Initialize LoadTimeWeaverAware beans early to allow for registering their

  transformers early.

  String[] weaverAwareNames = beanFactory.getBeanNamesForType (LoadTimeWeaverAware.

  class, false, false);

  for (String weaverAwareName : weaverAwareNames) {

  getBean(weaverAwareName);

 }

  // Stop using the temporary ClassLoader for type matching.

 beanFactory.setTempClassLoader(null);

 //冻结所有的 bean 定义,说明注册的 bean 定义将不被修改或任何进一步的处理。

 beanFactory.freezeConfiguration();

  // Instantiate all remaining (non-lazy-init) singletons.

 //初始化剩下的单实例(非惰性的)

 beanFactory.preInstantiateSingletons();

}

首先我们来了解一下 ConversionService 类所提供的作用。

1.ConversionService 的设置

之前我们提到过使用自定义类型转换器从 String 转换为 Date 的方式,那么,在 Spring 中还提供了另一种转换方式:使用 Converter。同样,我们使用一个简单的示例来了解下 Converter 的使用方式。

(1)定义转换器。

public class String2DateConverter implements Converter<String, Date> {

 @Override

  public Date convert(String arg0) {

   try {

    return DateUtils.parseDate(arg0,

     new String[] { "yyyy-MM-dd HH:mm:ss" });

   } catch (ParseException e) {

    return null;

  }

 }

}

(2)注册。

<bean id="conversionService"

 class="org.Springframework.context.support.ConversionServiceFactoryBean">

  <property name="converters">

  <list>

    <bean class="String2DateConverter" />

  </list>

 </property>

</bean>

(3)测试。

这样便可以使用 Converter 为我们提供的功能了,下面我们通过一个简便的方法来对此直接测试。

public void testStringToPhoneNumberConvert() {

  DefaultConversionService conversionService = new DefaultConversionService();

  conversionService.addConverter(new StringToPhoneNumberConverter());

  String phoneNumberStr = "010-12345678";

  PhoneNumberModel phoneNumber = conversionService.convert(phoneNumberStr, PhoneNumber

 Model.class);

  Assert.assertEquals("010", phoneNumber.getAreaCode());

}

通过以上的功能我们看到了 Converter 以及 ConversionService 提供的便利功能,其中的配置就是在当前函数中被初始化的。

2.冻结配置

冻结所有的 bean 定义,说明注册的 bean 定义将不被修改或进行任何进一步的处理。

public void freezeConfiguration() {

  this.configurationFrozen = true;

  synchronized (this.beanDefinitionMap) {

   this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.bean

  DefinitionNames);

 }

}

3.初始化非延迟加载

ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext 实例会创建并配置所有的单例 bean。通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。而这个实例化的过程就是在 finishBeanFactoryInitialization 中完成的。

public void preInstantiateSingletons() throws BeansException {

  if (this.logger.isInfoEnabled()) {

   this.logger.info("Pre-instantiating singletons in " + this);

 }

  List<String> beanNames;

  synchronized (this.beanDefinitionMap) {

   // Iterate over a copy to allow for init methods which in turn register new

   bean definitions.

   // While this may not be part of the regular factory bootstrap, it does

   otherwise work fine.

   beanNames = new ArrayList<String>(this.beanDefinitionNames);

 }

  for (String beanName : beanNames) {

   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

    if (isFactoryBean(beanName)) {

     final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_

    BEAN_PREFIX + beanName);

     boolean isEagerInit;

     if (System.getSecurityManager() != null && factory instanceof

     SmartFactoryBean) {

      isEagerInit = AccessController.doPrivileged(new PrivilegedAction

      <Boolean>() {

       public Boolean run() {

        return ((SmartFactoryBean<?>) factory).isEagerInit();

      }

      }, getAccessControlContext());

    }

     else {

      isEagerInit = (factory instanceof SmartFactoryBean &&

      ((SmartFactoryBean<?>) factory).isEagerInit());

    }

     if (isEagerInit) {

     getBean(beanName);

    }

   }

    else {

    getBean(beanName);

   }

  }

 }

}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。