这一篇介绍一下接下来几个方法
// Initialize message source for this context.
initMessageSource();
该方法主要是用来管理国际化文件
源码:
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
这里在启动的时候,会校验配置文件中是否有配置了name为 “messageSource”的bean
例如:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
那么工程需要建立
format_en_GB.properties,exceptions_en_GB.properties和windows_en_GB.properties
三个配置文件即可,在里面写入对应的国际化信息
假定上面的资源文件的内容为…
# in 'format.properties'
message=Alligators rock!
# in 'exceptions.properties'
argument.required=The '{0}' argument is required.
下面是测试代码。因为ApplicationContext
实现也都实现了MessageSource
接口,所以能被转型为MessageSource
接口
public static void main(String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("message", null, "Default", null);
System.out.println(message);
}
上述程序的输出结果将会是...
Alligators rock!
总而言之,我们在'beans.xml'
的文件中(在classpath根目录下)定义了一个messageSource
bean,通过它的basenames
属性引用多个资源文件;而basenames
属性值由list元素所指定的三个值传入,它们以文件的形式存在并被放置在classpath的根目录下(分别为format.properties
,exceptions.properties
和windows.properties
)。
接下来方法是
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
这个方法主要作用是
查找是否有name为 applicationEventMulticaster 的bean,如果有放到容器里,如果没有,初始化一个系统默认的放入容器
applicationEventMulticaster主要功能是容器内的事件广播,采用的是 观察者 设计模式,我们可以定义自己的被观察者和观察者
被观察者需要继承
ApplicationEvent
package com.uu.event;
public class Eventa extends org.springframework.context.ApplicationEvent{
private static final long serialVersionUID = 8580034046020586736L;
public Eventa(Object source) {
super(source);
}
}
观察者需要实现 ApplicationListener<Eventa> ,这里的泛型是指需要监听的被观察者,如果不写的话该观察者就会接收到所有的spring事件
package com.uu.event;
import org.springframework.context.ApplicationListener;
public class Listenera implements ApplicationListener<Eventa> {
public void onApplicationEvent(Eventa event) {
System.out.println(event.getSource().toString());
}
}
其中观察者需要在配置文件里进行注册或者注解,让其受spring管理;被观察者则不用注册;调用代码示例如下
package com.uu;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.uu.event.Eventa;
public class T {
public static void main(String[] args) {
ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("applicationContext.xml");
c.publishEvent(new Eventa("init-bean---"));
//System.out.println(c.getBean("b1"));
//AbstractApplicationContext ab;
}
}
结果:
十一月 16, 2017 1:31:11 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7b79688d: startup date [Thu Nov 16 13:31:11 CST 2017]; root of context hierarchy
十一月 16, 2017 1:31:11 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
十一月 16, 2017 1:31:11 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@72f2a1bd: defining beans [b1,l]; root of factory hierarchy
init-bean---
然后是
// Check for listener beans and register them.
registerListeners();
这个方法主要就是将我们定义的 ApplicationListener 放入容器中
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}