Spring源码学习(四):容器的功能扩展·二

目录

1.initMessageSource

2.initApplicationEventMulticaster

3.registerListeners

4.finishBeanFactoryInitialization

5.finishRefresh


到目前,容器的启动过程还剩下下面几个方法:

this.initMessageSource(); //初始化消息源,用于国际化
this.initApplicationEventMulticaster(); //初始化应用程序的事件广播器
this.onRefresh(); //空方法,作为扩展点
this.registerListeners(); //查找并注册Listener Bean
this.finishBeanFactoryInitialization(beanFactory); //初始化剩余的单例
this.finishRefresh(); //完成刷新,并通知相关监听器

1.initMessageSource

MessageSource的作用是进行国际化,initMessageSource方法源码如下:

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("messageSource")) {
            this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(this.getInternalParentMessageSource());
                }
            }
        } else {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton("messageSource", this.messageSource);
        }

    }

该方法首先在容器中查找是否有名为“messageSource”的Bean,如果有,则获取它,假如它是HierarchicalMessageSource类型,则为其设置ParentMessageSource;如果没有,则新建一个DelegatingMessageSource对象,并为其创建单例实例。无论哪种情况,都会将其赋给类成员变量messageSource。从这段代码中,可以看到,假如说我们自己实现了一个MessageSource,在XML配置时,其id属性必须是“messageSource”,否则将不会生效,这里隐含的另一个限制就是,容器内只能有一个MessageSource生效。

HierarchicalMessageSource和DelegatingMessageSource都是MessageSource的子类,前者的两个实现类ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,都是基于Java的ResourceBundle实现的,可以通过资源名加载国际化资源,ReloadableResourceBundleMessageSource可以在不重启程序的情况下更新国际化资源;DelegatingMessageSource主要用于父MessageSource。

需要提取出Message时,可以通过context.getMessage()方法,在ResourceBundleMessageSource中,该方法实际就是调用MessageSource的getMessageInternal方法,可以看到,MessageSource实质就是Locale和MessageFormat的封装:

    protected String getMessageInternal(@Nullable String code, @Nullable Object[] args, @Nullable Locale locale) {
        if (code == null) {
            return null;
        } else {
            if (locale == null) {
                locale = Locale.getDefault();
            }
            Object[] argsToUse = args;
            if (!this.isAlwaysUseMessageFormat() && ObjectUtils.isEmpty(args)) {
                String message = this.resolveCodeWithoutArguments(code, locale);
                if (message != null) {
                    return message;
                }
            } else {
                argsToUse = this.resolveArguments(args, locale);
                MessageFormat messageFormat = this.resolveCode(code, locale);
                if (messageFormat !=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值