国际化和event
机制是通过initMessageSource,initApplicationEventMulticaster
来实现的。
两者都是查找名称为特定名称,类型为特定的类型赋值给applicationContext
内部的成员变量,如果没找到则新建。
/**--org.springframework.context.support.AbstractApplicationContext--**/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//首先判断是不是存在名字为MESSAGE_SOURCE_BEAN_NAME的bean或者beanDefinition。
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//获取名称为messageSource,类型为MessageSource,并赋值给messageSource
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 + "]");
}
}
}
国际化
MessageFormat
ResourceBundle
MessageSource
如何使用国际化
- 注册一个
beanName=messageSource
的bean
,该bean
要实现MessageSource
方法. spring
提供了MessageSource
的实现类ResourceBundleMessageSource
,本质上是使用java
自身提供的国际化实现.- 实例
<beans> <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> </beans>
The example assumes that you have three resource bundles called format_en_GB.properties
, exceptions
and windows
defined in your classpath
EventListener
applicationContext
是委托ApplicationEventMulticaster
和SimpleApplicationEventMulticaster
完成事件监听的.最终所有的ApplicationListener
队友注册到ApplicationEventMulticaster
中
ApplicationListener
接口和ApplicationEvent
抽象类- 4.2 版本后的
EventListener
注解 - 配置资源中的
ApplicationListener
接口的类是通过ApplicationListenerDetector
(BeanPostProcessor
的实现类)来注册到ApplicationEventMulticaster
中
代码
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.此处不提前获取 `create` 对应的`Listener`.
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
- 处理手动注册的
ApplicationListener
- 查询出所有的
ApplicationListener
的beanName
并注册到applicationEventMulticaster
中. - 如果能提前发布
event
, 将earlyApplicationEvents
发布出去.
@EventListener
大致处理流程是扫描所有 实现
EventListener
注解的方法,将其转化为 ApplicationListener
. 转化的动作是由 EventListenerFactory
实现。
EventListenerFactory : 将方法转化为 ApplicationListener
.
为什么使用EventListenerFactory
主要是可能有不同的事件类型.例如普通event
和 事务event
.两个实现类分别为TransactionalEventListenerFactory
和 DefaultEventListenerFactory
.
EventListenerMethodProcessor
将调用EventListenerFactory
将符合条件的Method
创建成ApplicationListener
。
EventListenerMethodProcessor
该类实现 BeanFactoryPostProcessor
和 SmartInitializingSingleton
. 其功能主要在 所有的BeanDefinition
加载完毕,以及所有的 singleton
类 创建完成后调用。 代码如下
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
List<EventListenerFactory> factories = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(factories);
this.eventListenerFactories = factories;
}
在BeanDefinition
加载完毕后,调用beanFactory
提前创建所有实现了 EventListenerFactory
的bean
.
AnnotationConfigUtils.registerAnnotationConfigProcessors
会设置 DefaultEventListenerFactory
.
在所有的singleton
创建完成后,
- 遍历所有的
singleton
- 如果
bean
不是scopedTarge
.(不知道干啥的) - 判断
bean
的class
.(注意代理类的class
获取,使用AutoProxyUtils
类获取代理类的class
) - 如果是
class
实现了ScopedObject
,特殊处理下(不知道干啥) - 扫描所有满足条件的
method
调用EventListenerFactory
生成ApplicationListener
@Override
public void afterSingletonsInstantiated() {
ConfigurableListableBeanFactory beanFactory = this.beanFactory;
Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
Class<?> type = null;
try {
type = AutoProxyUtils.determineTargetClass(beanFactory, beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
}
}
if (type != null) {
if (ScopedObject.class.isAssignableFrom(type)) {
try {
Class<?> targetClass = AutoProxyUtils.determineTargetClass(
beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));
if (targetClass != null) {
type = targetClass;
}
}
catch (Throwable ex) {
// An invalid scoped proxy arrangement - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
}
}
}
try {
//创建方法
processBean(beanName, type);
}
catch (Throwable ex) {
throw new BeanInitializationException("Failed to process @EventListener " +
"annotation on bean with name '" + beanName + "'", ex);
}
}
}
}
}
processBean
- 寻找所有
@EventListener
的方法。 - 通过
EventListenerFactory
来创建ApplicationListener
(默认都是ApplicationListenerMethodAdapter
) - 注册到
applicationContext
中。
private void processBean(final String beanName, final Class<?> targetType) {
if (!this.nonAnnotatedClasses.contains(targetType) &&
AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
!isSpringContainerClass(targetType)) {
Map<Method, EventListener> annotatedMethods = null;
try {
//查询所有@EventListener 的方法。
annotatedMethods = MethodIntrospector.selectMethods(targetType,
(MethodIntrospector.MetadataLookup<EventListener>) method ->
AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
}
catch (Throwable ex) {
// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
}
}
//如果没有相应的方法,缓存下来。避免下次判断
if (CollectionUtils.isEmpty(annotatedMethods)) {
this.nonAnnotatedClasses.add(targetType);
if (logger.isTraceEnabled()) {
logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
}
}
else {
// Non-empty set of methods
ConfigurableApplicationContext context = this.applicationContext;
Assert.state(context != null, "No ApplicationContext set");
List<EventListenerFactory> factories = this.eventListenerFactories;
Assert.state(factories != null, "EventListenerFactory List not initialized");
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
//调用EventListenerFactory 生成 ApplicationListener
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
}
context.addApplicationListener(applicationListener);
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
beanName + "': " + annotatedMethods);
}
}
}
}
如何通过事件找到对应的applicationListenner
通常我们发布事件都是之间通过applicationContext.publishEvent()
或者 注入一个 ApplicationEventMulticaster
来 发布事件的。本质上都是调用 applicationContext.applicationEventMulticaster.publishEvent(Object event, @Nullable ResolvableType eventType)
来发布事件。只不过 applicationContext.publishEvent()
使用了包装模式 能够将普通的对象转化为applicationEvent
- 事件分为两种。 一种是直接实现了
ApplicationEvent
,一种就是原始的object
- 对于
ApplicationEvent
不需要直接处理发布,对于未实现的,需要解析出eventType
, 用来匹配applicationListenner
- 事件也会在
parent
中发布 - 事件会在支持对应
event
的Listenner
中调用。
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
查找满足条件的listener
的方法为 org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
,
其中判断listener
是否支持相应event
的方法是 org.springframework.context.event.AbstractApplicationEventMulticaster#supportsEvent(org.springframework.context.ApplicationListener<?>, org.springframework.core.ResolvableType, java.lang.Class<?>)
,
而supportsEvent
最终是调用GenericApplicationListener
里面的 supportsEventType
和 supportsSourceType
来判断是否支持的. 而 ApplicationListenerMethodAdapter
实现了 GenericApplicationListener
我们假设事件为A.class的对象. 则对应的 applicationEvent = new PayloadApplicationEvent(context,a)
.对应的eventType = ResolvableType.forClassWithGenerics(applicationContext.class,A.class)
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
//source = a
Object source = event.getSource();
//sourceType=A.class
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
//从缓存获取,缓存中没有 通过 retrieveApplicationListeners 方法获取
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
Collection<ApplicationListener<?>> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {
....
for (ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
try {
Class<?> listenerType = beanFactory.getType(listenerBeanName);
if (listenerType == null || supportsEvent(listenerType, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListenerBeans.add(listenerBeanName);
}
allListeners.add(listener);
}
}
}
catch (NoSuchBeanDefinitionException ex) {
...
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
//org.springframework.context.event.ApplicationListenerMethodAdapter#supportsEventType
//eventType = ResolvableType.forClassWithGenerics(applicationContext.class,A.class)
public boolean supportsEventType(ResolvableType eventType) {
for (ResolvableType declaredEventType : this.declaredEventTypes) {
//declaredEventTypes 是冲 @EventListener注解中获取的 ResolvableType.forClass 和 监听方法参数中的 ResolvableType.forMethodParameter.
//而 eventType 的 是raw class = PayloadApplicationEvent.class,
//泛型参数为 A.class的 ResolvableType . 所以第一步肯定不是
if (declaredEventType.isAssignableFrom(eventType)) {
return true;
}
//明显走该条件
else if (PayloadApplicationEvent.class.isAssignableFrom(eventType.getRawClass())) {
ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
if (declaredEventType.isAssignableFrom(payloadType)) {
return true;
}
}
}
return eventType.hasUnresolvableGenerics();
}
@EventListener
生成的ApplicationListener
为ApplicationListenerMethodAdapter
. 其处理方法为
- 解析出监听方法参数。
- 如果没有参数或者不满足condition , 不处理事件
@EventListenner
注解的事件类型大于方法参数中声明的事件类型
public void processEvent(ApplicationEvent event) {
//解析出监听方法需要的参数
Object[] args = resolveArguments(event);
//如果没有参数或者condition不满足,则不调用方法
if (shouldHandle(event, args)) {
Object result = doInvoke(args);
if (result != null) {
handleResult(result);
}
else {
logger.trace("No result object given - no result to handle");
}
}
}
@Nullable
protected Object[] resolveArguments(ApplicationEvent event) {
//获取event的对应的 ResolvableType。对应实现了applicationEvent的事件,就是事件类本身的class信息。
ResolvableType declaredEventType = getResolvableType(event);
//如果未获取到event的 resolvableType,直接返回null
if (declaredEventType == null) {
return null;
}
//如果监听方法没有参数,则直接返回一个object[0]
if (this.method.getParameterCount() == 0) {
return new Object[0];
}
//获取 ResolvableType 的class 。
Class<?> declaredEventClass = declaredEventType.toClass();
//如果不是 ApplicationEvent 并且event是 PayloadApplicationEvent。
if (!ApplicationEvent.class.isAssignableFrom(declaredEventClass) &&
event instanceof PayloadApplicationEvent) {
Object payload = ((PayloadApplicationEvent<?>) event).getPayload();
//判断payLoad是否是改生命对象的
if (declaredEventClass.isInstance(payload)) {
return new Object[] {payload};
}
}
return new Object[] {event};
}
@Nullable
private ResolvableType getResolvableType(ApplicationEvent event) {
ResolvableType payloadType = null;
if (event instanceof PayloadApplicationEvent) {
PayloadApplicationEvent<?> payloadEvent = (PayloadApplicationEvent<?>) event;
ResolvableType eventType = payloadEvent.getResolvableType();
if (eventType != null) {
payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
}
}
for (ResolvableType declaredEventType : this.declaredEventTypes) {
Class<?> eventClass = declaredEventType.toClass();
if (!ApplicationEvent.class.isAssignableFrom(eventClass) &&
payloadType != null && declaredEventType.isAssignableFrom(payloadType)) {
return declaredEventType;
}
//对应applicationEvent, 直接判断 是不是 ApplicationListenerMethodAdapter 能处理event的实例
if (eventClass.isInstance(event)) {
return declaredEventType;
}
}
return null;
}
很好奇 为什么不直接用class
进行事件和参数的比较,非要用ResolvableType
来比较