ApplicationListener机制
Posted 恒奇恒毅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ApplicationListener机制相关的知识,希望对你有一定的参考价值。
EventListener注解支持
什么时候解析EventListener注解?
EventListener
注解由EventListenerMethodProcessor
进行解析。
EventListenerMethodProcessor
实现了SmartInitializingSingleton
,在方法afterSingletonsInstantiated中对EventListener
进行处理。
@Override
public void afterSingletonsInstantiated()
List<EventListenerFactory> factories = getEventListenerFactories();
String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames)
if (!ScopedProxyUtils.isScopedTarget(beanName))
Class<?> type = null;
try
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(), 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
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(),
ScopedProxyUtils.getTargetBeanName(beanName));
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(factories, beanName, type);
catch (Throwable ex)
throw new BeanInitializationException("Failed to process @EventListener " +
"annotation on bean with name '" + beanName + "'", ex);
/**
* Return the @link EventListenerFactory instances to use to handle
* @link EventListener annotated methods.
*/
protected List<EventListenerFactory> getEventListenerFactories()
Map<String, EventListenerFactory> beans = this.applicationContext.getBeansOfType(EventListenerFactory.class);
List<EventListenerFactory> allFactories = new ArrayList<EventListenerFactory>(beans.values());
AnnotationAwareOrderComparator.sort(allFactories);
return allFactories;
protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType)
if (!this.nonAnnotatedClasses.contains(targetType))
Map<Method, EventListener> annotatedMethods = null;
try
annotatedMethods = MethodIntrospector.selectMethods(targetType,
new MethodIntrospector.MetadataLookup<EventListener>()
@Override
public EventListener inspect(Method method)
return 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
for (Method method : annotatedMethods.keySet())
for (EventListenerFactory factory : factories)
if (factory.supportsMethod(method))
Method methodToUse = AopUtils.selectInvocableMethod(
method, this.applicationContext.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter)
((ApplicationListenerMethodAdapter) applicationListener)
.init(this.applicationContext, this.evaluator);
this.applicationContext.addApplicationListener(applicationListener);
break;
if (logger.isDebugEnabled())
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
beanName + "': " + annotatedMethods);
首先从容器中获取EventListenerFactory
的实现类,用于产生ApplicationListener
。然后获取容器中的所有bean进行EventListener
解析。
在processBean方法中,对所有Bean的所有标注了EventListener
的方法进行遍历,所有的EventListenerFactory
产生一个ApplicationListener
,通过ApplicationConetxt#addApplicationListener放入容器中,底层实现加入了SimpleApplicationEventMulticaster
。
Method methodToUse = AopUtils.selectInvocableMethod(
method, this.applicationContext.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter)
((ApplicationListenerMethodAdapter) applicationListener)
.init(this.applicationContext, this.evaluator);
this.applicationContext.addApplicationListener(applicationListener);
系统默认的EventListenerFactory
是DefaultEventListenerFactory
,和EventListenerMethodProcessor
都是在org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)方法中注册的这个类。说实在的EventListenerFactory叫ApplicationListenerFactory是不是更好呢?
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME))
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME))
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
以上是关于ApplicationListener机制的主要内容,如果未能解决你的问题,请参考以下文章