@eventlistener使用方式
package com.cyl.listener; import org.springframework.context.applicationevent; import org.springframework.context.payloadapplicationevent; import org.springframework.context.event.eventlistener; import org.springframework.stereotype.component; @component public class cylorderseclistener { @eventlistener public void listen(applicationevent event) { system.out.println(event); } }
@eventlistener实现原理
主要通过eventlistenermethodprocessor和defaulteventlistenerfactory这两个类实现。
- eventlistenermethodprocessor的作用是识别所有使用eventlistener注解的方法
- defaulteventlistenerfactory将eventlistenermethodprocessor识别出的方法封装成为监听器类
以代码new annotationconfigapplicationcontext为入口调试代码去讲解eventlistenermethodprocessor和defaulteventlistenerfactory如何去生效的
package com.cyl; import org.springframework.context.annotation.annotationconfigapplicationcontext; public class test { public static void main(string[] args) { // 创建一个spring容器 annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(); context.register(appconfig.class); context.refresh(); } }
1.引入时机-获取bean定义
eventlistenermethodprocessor和defaulteventlistenerfactory的bean定义信息在容器初始化最开始阶段,defaultlistablebeanfactory实例化后,被注册到defaultlistablebeanfactory的beandefinitionmap中。
执行new annotationconfigapplicationcontext,会优先执行父类 genericapplicationcontex构造方法,实例化一个bean工厂
genericapplicationcontext执行完后,会实例化annotatedbeandefinitionreader,可以理解为容器内一个bean定义阅读器,负责将bean定义注册到bean工厂中。
实例化annotatedbeandefinitionreader会注册一些bean定义到bean工厂中,其中就包括了eventlistenermethodprocessor和defaulteventlistenerfactory。
2.实例化时机-new对象
只引入了bean定义,还未真正对bean进行实例化,实例化步骤是在spring执行refresh时
走到方法内,会调用
org.springframework.context.support.postprocessorregistrationdelegate#invokebeanfactorypostprocessors(org.springframework.beans.factory.config.configurablelistablebeanfactory, java.util.list<org.springframework.beans.factory.config.beanfactorypostprocessor>)
关注代码184行,获取普通beanfactorypostprocessor类,而eventlistenermethodprocessor实现了beanfactorypostprocessor,此处打断点也会获取该类名
由于eventlistenermethodprocessor没有实现priorityordered或者ordered接口,所以就被放入了nonorderedpostprocessornames中最后被执行
当执行beanfactory.getbean(ppname, beanfactorypostprocessor.class)会进行实例化走到eventlistenermethodprocessor的构造函数中
到此eventlistenermethodprocessor实例化好了,代码继续执行
会执行到eventlistenermethodprocessor.postprocessbeanfactory(),在这里实例化defaulteventlistenerfactory
3.作用时机->将加了eventlistener注解的方法识别出来
并封装为监听器,加载spring容器中
当执行
org.springframework.beans.factory.support.defaultlistablebeanfactory#preinstantiatesingletons
初始化后,
因eventlistenermethodprocessor实现了smartinitializingsingleton,
而所有实现smartinitializingsingleton类对象都需要在所有对象初始化后再执行aftersingletonsinstantiated
即:
org.springframework.beans.factory.support.defaultlistablebeanfactory#preinstantiatesingletons
@override public void preinstantiatesingletons() throws beansexception { if (logger.istraceenabled()) { logger.trace("pre-instantiating singletons in " + this); } // 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<string> beannames = new arraylist<>(this.beandefinitionnames); // trigger initialization of all non-lazy singleton beans... for (string beanname : beannames) { // 获取合并后的beandefinition rootbeandefinition bd = getmergedlocalbeandefinition(beanname); if (!bd.isabstract() && bd.issingleton() && !bd.islazyinit()) { if (isfactorybean(beanname)) { // 获取factorybean对象 object bean = getbean(factory_bean_prefix + beanname); if (bean instanceof factorybean) { factorybean<?> factory = (factorybean<?>) bean; boolean iseagerinit; if (system.getsecuritymanager() != null && factory instanceof smartfactorybean) { iseagerinit = accesscontroller.doprivileged( (privilegedaction<boolean>) ((smartfactorybean<?>) factory)::iseagerinit, getaccesscontrolcontext()); } else { iseagerinit = (factory instanceof smartfactorybean && ((smartfactorybean<?>) factory).iseagerinit()); } if (iseagerinit) { // 创建真正的bean对象(getobject()返回的对象) getbean(beanname); } } } else { // 创建bean对象 getbean(beanname); } } } // 所有的非懒加载单例bean都创建完了后 // trigger post-initialization callback for all applicable beans... for (string beanname : beannames) { object singletoninstance = getsingleton(beanname); if (singletoninstance instanceof smartinitializingsingleton) { startupstep smartinitialize = this.getapplicationstartup().start("spring.beans.smart-initialize") .tag("beanname", beanname); smartinitializingsingleton smartsingleton = (smartinitializingsingleton) singletoninstance; if (system.getsecuritymanager() != null) { accesscontroller.doprivileged((privilegedaction<object>) () -> { smartsingleton.aftersingletonsinstantiated(); return null; }, getaccesscontrolcontext()); } else { smartsingleton.aftersingletonsinstantiated(); } smartinitialize.end(); } } }
当执行smartsingleton.aftersingletonsinstantiated();就会调到
org.springframework.context.event.eventlistenermethodprocessor#aftersingletonsinstantiated
eventlistenermethodprocessor真正的处理逻辑来了,主要看第38行关键方法
@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)) { // 拿到当前bean对象的类型 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); } } } } }
org.springframework.context.event.eventlistenermethodprocessor#processbean,关注下面代码的注释,主要逻辑就是会遍历所有单例池中的对象,找到对象中加@eventlistener注解的方法,然后通过eventlistenerfactory将方法设置成监听器,注册到spring容器中
private void processbean(final string beanname, final class<?> targettype) { if (!this.nonannotatedclasses.contains(targettype) && annotationutils.iscandidateclass(targettype, eventlistener.class) && !isspringcontainerclass(targettype)) { // 找到所有加了@eventlistener注解的方法 map<method, eventlistener> annotatedmethods = null; try { 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) { // 利用eventlistenerfactory来对加了@eventlistener注解的方法生成applicationlistener对象 if (factory.supportsmethod(method)) { method methodtouse = aoputils.selectinvocablemethod(method, context.gettype(beanname)); 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); } } } }
发布事件,生效
容器初始化后,设置的监听器会收到容器初始化完成的事件,然后执行自定义的监听事件
容器初始化最后阶段,即执行org.springframework.context.support.abstractapplicationcontext#finishrefresh
最终效果图为:
总结
eventlistenermethodprocessor和defaulteventlistenerfactory两个类是注解eventlistener的逻辑处理类,先在spring容器初始化阶段先显示引入这两个类的bean定义,然后spring容器在执行beanfactory的后置处理器逻辑时,对这两个类进行实例化;
最后待所有非懒加载单例bean都初始化完后,执行eventlistenermethodprocessor的aftersingletonsinstantiated即初始化后方法,识别出所有加了注解eventlistener的方法,将这些方法用defaulteventlistenerfactory封装成监听器类,注册到spring容器中。
待发布事件时,再从spring容器中获取所有监听器类,回调监听方法。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论