eventlistener java_EventListener原理

目录

流程

容器的刷新流程如下:

public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

// Prepare this context for refreshing.

prepareRefresh();

// Tell the subclass to refresh the internal bean factory.

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.

prepareBeanFactory(beanFactory);

try {

// Allows post-processing of the bean factory in context subclasses.

postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.

invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.

registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.

initMessageSource();

// Initialize event multicaster for this context.

initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.

onRefresh();

// Check for listener beans and register them.

registerListeners();

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

finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.

finishRefresh();

}

finally {

// Reset common introspection caches in Spring's core, since we

// might not ever need metadata for singleton beans anymore...

resetCommonCaches();

}

}

}

其中与EventListener有关联的步骤

initApplicationEventMulticaster(); 初始化事件多播器

registerListeners(); 注册Listener到多播器

finishBeanFactoryInitialization(beanFactory); 涉及将@EventListener转为普通Listener

finishRefresh(); 发布容器刷新完成事件ContextRefreshedEvent

initApplicationEventMulticaster()

protected void initApplicationEventMulticaster() {

ConfigurableListableBeanFactory beanFactory = getBeanFactory();

//找applicationEventMulticaster的组件

if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {

this.applicationEventMulticaster =

beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);

if (logger.isDebugEnabled()) {

logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");

}

}

else {

//没有就创建一个

this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);

//注册到beanFactory

beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

if (logger.isDebugEnabled()) {

logger.debug("Unable to locate ApplicationEventMulticaster with name '" +

APPLICATION_EVENT_MULTICASTER_BEAN_NAME +

"': using default [" + this.applicationEventMulticaster + "]");

}

}

}

registerListeners()

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 listenerBeanName : listenerBeanNames) {

getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

}

// Publish early application events now that we finally have a multicaster...

Set earlyEventsToProcess = this.earlyApplicationEvents;

this.earlyApplicationEvents = null;

if (earlyEventsToProcess != null) {

for (ApplicationEvent earlyEvent : earlyEventsToProcess) {

getApplicationEventMulticaster().multicastEvent(earlyEvent);

}

}

}

finishRefresh()

protected void finishRefresh() {

// Clear context-level resource caches (such as ASM metadata from scanning).

clearResourceCaches();

// Initialize lifecycle processor for this context.

initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.

getLifecycleProcessor().onRefresh();

// Publish the final event.

//发布事件

publishEvent(new ContextRefreshedEvent(this));

// Participate in LiveBeansView MBean, if active.

LiveBeansView.registerApplicationContext(this);

}

publishEvent() 发布事件,我们也可以手动调用容器的publishEvent() 方法来发布事件

ApplicationContext.publishEvent(new MyEvent("test"));

publishEvent()

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {

// 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);

}

}

}

@EventListener处理

原理:通过EventListenerMethodProcessor来处理@Eventlstener

public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware

EventListenerMethodProcessor 是一个 SmartInitializingSingleton。

SmartInitializingSingleton什么时候执行呢?

在Refresh()

​ -> finishBeanFactoryInitialization(beanFactory);

​ -> DefaultListableBeanFactory#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {

// 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.

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

// Trigger initialization of all non-lazy singleton beans...

for (String beanName : beanNames) {

RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

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

if (isFactoryBean(beanName)) {

Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

if (bean instanceof FactoryBean) {

final FactoryBean> factory = (FactoryBean>) bean;

boolean isEagerInit;

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

isEagerInit = AccessController.doPrivileged((PrivilegedAction)

((SmartFactoryBean>) factory)::isEagerInit,

getAccessControlContext());

}

else {

isEagerInit = (factory instanceof SmartFactoryBean &&

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

}

if (isEagerInit) {

getBean(beanName);

}

}

}

else {

// 创建bean

getBean(beanName);

}

}

}

// Trigger post-initialization callback for all applicable beans...

for (String beanName : beanNames) {

Object singletonInstance = getSingleton(beanName);

if (singletonInstance instanceof SmartInitializingSingleton) {

final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;

if (System.getSecurityManager() != null) {

AccessController.doPrivileged((PrivilegedAction) () -> {

smartSingleton.afterSingletonsInstantiated();

return null;

}, getAccessControlContext());

}

else {

smartSingleton.afterSingletonsInstantiated();

}

}

}

}

preInstantiateSingletons 前半部分主要是遍历beanNames 创建Bean。创建完bean后判断各bean是不是SmartInitializingSingleton,如果是则执行 smartSingleton.afterSingletonsInstantiated()方法。

//org.springframework.context.event.EventListenerMethodProcessor#afterSingletonsInstantiated

public void afterSingletonsInstantiated() {

List factories = getEventListenerFactories();

ConfigurableApplicationContext context = getApplicationContext();

String[] beanNames = context.getBeanNamesForType(Object.class);

for (String beanName : beanNames) {

if (!ScopedProxyUtils.isScopedTarget(beanName)) {

Class> type = null;

try {

type = AutoProxyUtils.determineTargetClass(context.getBeanFactory(), beanName);

}

if (type != null) {

if (ScopedObject.class.isAssignableFrom(type)) {

try {

Class> targetClass = AutoProxyUtils.determineTargetClass(

context.getBeanFactory(), ScopedProxyUtils.getTargetBeanName(beanName));

if (targetClass != null) {

type = targetClass;

}

}

}

try {

//处理bean

processBean(factories, beanName, type);

}

}

}

}

}

protected void processBean(

final List factories, final String beanName, final Class> targetType) {

//没有注解的class

if (!this.nonAnnotatedClasses.contains(targetType)) {

Map annotatedMethods = null;

try {

//查找被注解EventListener的方法

annotatedMethods = MethodIntrospector.selectMethods(targetType,

(MethodIntrospector.MetadataLookup) 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 = getApplicationContext();

for (Method method : annotatedMethods.keySet()) {

for (EventListenerFactory factory : factories) {

if (factory.supportsMethod(method)) {

Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));

//创建applicationListener,通过Adapter将注解形式的listener转换为普通的listener

ApplicationListener> applicationListener =

factory.createApplicationListener(beanName, targetType, methodToUse);

if (applicationListener instanceof ApplicationListenerMethodAdapter) {

((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);

}

//添加listner到applicationContext

context.addApplicationListener(applicationListener);

break;

}

}

}

if (logger.isDebugEnabled()) {

logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +

beanName + "': " + annotatedMethods);

}

}

}

}

查找类中标注@EventListener的方法

EventListenerFactory.createApplicationListener(beanName, targetType, methodToUse) 构造listener

添加listener到Context中

如果有applicationEventMulticaster,添加到ApplicationContext.applicationEventMulticaster中

如果没有applicationEventMulticaster,添加到ApplicationContext.applicationListeners中。

转载至链接:https://my.oschina.net/u/1245414/blog/1926461

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值