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
eventlistener java_EventListener原理相关推荐
- SpringBoot中@EventListener注解的使用
一:背景 在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监 ...
- SpringBoot 使用注解实现消息广播功能
背景 在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监听也 ...
- 回炉Spring--事务及Spring源码
声明式事务 配置文件信息: /*** @EnableTransactionManagement 开启基于注解的事务管理功能* 1.配置数据源* 2.配置事务管理器来管理事务* 3.给方法上标注 @Tr ...
- 论如何优雅地知道OkHttp的请求时间
/ 今日科技快讯 / 虾米音乐宣布2021年2月5日0点停止服务,停止所有歌曲试听.下载.评论等所有音乐内容消费场景,停止个人资料导出或下载,仅保留账号资产处理.网页端音乐人提现服务.3月5日 ...
- OkHttp3详细使用教程
OkHttp介绍 OkHttp官网地址:http://square.github.io/okhttp/ OkHttp GitHub地址:https://github.com/square/okhttp ...
- 【spring】Spring事件监听器ApplicationListener的使用与源码分析
ApplicationEvent以及Listener是Spring为我们提供的一个事件监听.订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性. ...
- java signature 性能_Java常见bean mapper的性能及原理分析
背景 在分层的代码架构中,层与层之间的对象避免不了要做很多转换.赋值等操作,这些操作重复且繁琐,于是乎催生出很多工具来优雅,高效地完成这个操作,有BeanUtils.BeanCopier.Dozer. ...
- SpringCloudAlibaba:Nacos实现原理详解
欢迎关注方志朋的博客,回复"666"获面试宝典 Nacos 架构 Provider APP:服务提供者 Consumer APP:服务消费者 Name Server:通过VIP(V ...
- Nacos实现原理详解
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://blog.csdn.net/cold___play/article/details/108032204 Nac ...
最新文章
- OpenCV常遇问题解决方法汇总
- web页面事件无响应,元素点击不到
- 一次完整的HTTP事务是怎样一个过程
- 非静态成员函数的非法调用错误
- 自定义注解与validation结合使用案例
- dedecms织梦仿麦站网模板源码下载站源码
- android 应用区高度,Android创建显示区高度可以调整的ScrollView
- Linux 五种I/O模型
- python中文视频教程-中谷教育python中文视频教程(全38集)
- MySQL存储过程(四)——存储过程循环流控语句
- 余额宝宣布开放 中欧基金首批入驻
- 《机会的数学》--陈希孺
- 手机wap网站制作教程
- 解决github下载及访问不稳定问题
- java 实心圆,如何用css3实现实心圆
- mysql字符集校对_MySQL字符集与校对
- 跳跃表(SkipList)
- html效果浮窗效果,jQuery简单实现中间浮窗效果
- SpringMVC Web实现文件上传下载功能实例解析
- 微信小程序模仿拼多多APP地址选择样式