@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容器中获取所有监听器类,回调监听方法。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论