最近在做公司的业务需要用到事件通知,比如启动成功打印日志,通知其他业务做相应的操作,就用到了spring的事件通知机制。
spring的事件通知本质上就是发布-订阅,即生产者-消费者;体现了观察者设计模式或者回调通知,那么spring新加坡英语的事件是如何使用的?
有3要素:发布者–>事件–>监听者
spring的事件必须依赖spring容器,所以我在写demo的时候,需要spring-boot-starter。
<dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter</artifactid> <version>2.1.1.relea</version> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <version>1.18.4</version> </dependency> </dependencies>
spring的事件定义在applicationevent类中,我们可以根据自己的需要自定义事件实体javabean。
@datapublic class testspringevent extends applicationevent { /** * create a new applicationevent. * * @param source the object on which the event initially occurred (never {@code null}) */ public testspringevent(object source) { super(source); } private integer code; private string message; }
跟踪源码:
public abstract class applicationevent extends eventobject { /** u rialversionuid from spring 1.2 for interoperability. */private static final long rialversionuid = 7099057708183571937l; /** system time when the event happened. */private final long timestamp; /** * create a new applicationevent. * @param source the object on which the event initially occurred (never {@code null}) */public applicationevent(object source) {super(source);this.timestamp = system.currenttimemillis();} /** * return the system time in milliconds when the event happened. */public final long gettimestamp() {return this.timestamp;} }
可以看出applicationevent有属性时间戳,即事件的产生的时间,并有object source属性,这个source是有特定意义的,官方的doc是the object on which the event initially occurred.即发布事件的实体类。
进一步跟踪
public class eventobject implements java.io.rializable { private static final long rialversionuid = 5516075349620653480l; /** * the object on which the event initially occurred. */ protected transient object source; /** * constructs a prototypical event. * * @param source the object on which the event initially occurred. * @exception illegalargumentexception if source is null. */ public eventobject(object source) { if (source == null) throw new illegalargumentexception("null source"); this.source = source; } /** * the object on which the event initially occurred. * * @return the object on which the event initially occurred. */ public object getsource() { return source; } /** * returns a string reprentation of this eventobject. * * @return a a string reprentation of this eventobject. */ public string tostring() { return getclass().getname() + "[source=" + source + "]"; }}
定义了一个事件发生的不能序列化的对象
spring事件的监听由applicationlistener定义,我们写2个,来测试监听它执行的顺序
@componentpublic class testapplicationlistener implements applicationlistener<testspringevent> { //@async public void onapplicationevent(testspringevent event) { system.out.println("code is:\t" + event.getcode() + ",\tmessage is:\t" + event.getmessage()); }} @componentpublic class testapplicationlistenercopy implements applicationlistener<testspringevent> { //@async public void onapplicationevent(testspringevent event) { system.out.println("2:code is:\t" + event.getcode() + ",\tmessage is:\t" + event.getmessage()); }}
跟踪代码,可以看出applicationlistener是一个函数式接口
@functionalinterfacepublic interface applicationlistener<e extends applicationevent> extends eventlistener { /** * handle an application event. * @param event the event to respond to */void onapplicationevent(e event); }
spring事件监听器的默认是单线程同步执行,异步执行需要加上spring的@async注解,或者自定义线程池实现.
也可以使用@eventlistener
package com.feng.spring.listener; import com.feng.spring.event.testspringevent;import org.springframework.context.event.eventlistener;import org.springframework.scheduling.annotation.async;import org.springframework.stereotype.component; @componentpublic class testapplicationlistener2{ //@async @eventlistener public void onapplicationevent(testspringevent event) { system.out.println("step2:code is:\t" + event.getcode() + ",\tmessage is:\t" + event.getmessage()); }} @componentpublic class testapplicationlistener2copy { //@async @eventlistener public void onapplicationevent(testspringevent event) { system.out.println("step3:code is:\t" + event.getcode() + ",\tmessage is:\t" + event.getmessage()); }}
同理写2个实现
spring的事件的发布定义在applicationeventpublisher类中,而applicationcontext继承了这个类,因此applicationcontext具有发布事件的能力,而且已经注入spring的bean容器中,可直接获取。
public class springeventmain { public static void main(string[] args) { annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(); context.scan(springeventmain.class.getcanonicalname()); context.refresh(); testspringevent testspringevent = new testspringevent(new springeventmain()); testspringevent.tcode(10000); testspringevent.tmessage("---------my spring task event------------"); context.publishevent(testspringevent); }}
注意:
new testspringevent(new springeventmain())
这里的source是传入发布事件的实例对象。
运行后打印如下日志:
/software/jdk1.8.0_191/bin/java -javaagent:/software/ideaide/lib/idea_rt.jar=36631:/software/ideaide/bin -dfile.encoding=utf-8 -classpath /software/jdk1.8.0_191/jre/lib/charts.jar:/software/jdk1.8.0_191/jre/lib/deploy.jar:/software/jdk1.8.0_191/jre/lib/ext/cldrdata.jar:/software/jdk1.8.0_191/jre/lib/ext/dnsns.jar:/software/jdk1.8.0_191/jre/lib/ext/jaccess.jar:/software/jdk1.8.0_191/jre/lib/ext/jfxrt.jar:/software/jdk1.8.0_191/jre/lib/ext/localedata.jar:/software/jdk1.8.0_191/jre/lib/ext/nashorn.jar:/software/jdk1.8.0_191/jre/lib/ext/sunec.jar:/software/jdk1.8.0_191/jre/lib/ext/sunjce_provider.jar:/software/jdk1.8.0_191/jre/lib/ext/sunpkcs11.jar:/software/jdk1.8.0_191/jre/lib/ext/zipfs.jar:/software/jdk1.8.0_191/jre/lib/javaws.jar:/software/jdk1.8.0_191/jre/lib/jce.jar:/software/jdk1.8.0_191/jre/lib/jfr.jar:/software/jdk1.8.0_191/jre/lib/jfxswt.jar:/software/jdk1.8.0_191/jre/lib/js.jar:/software/jdk1.8.0_191/jre/lib/management-agent.jar:/software/jdk1.8.0_191/jre/lib/plugin.jar:/software/jdk1.8.0_191/jre/lib/resources.jar:/software/jdk1.8.0_191/jre/lib/rt.jar:/home/huahua/ideaprojects/feng/spring-event/target/class:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.1.relea/spring-boot-starter-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot/2.1.1.relea/spring-boot-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-context/5.1.3.relea/spring-context-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-aop/5.1.3.relea/spring-aop-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-beans/5.1.3.relea/spring-beans-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-expression/5.1.3.relea/spring-expression-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.relea/spring-boot-autoconfigure-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.1.relea/spring-boot-starter-logging-2.1.1.relea.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/home/huahua/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.1/log4j-to-slf4j-2.11.1.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar:/home/huahua/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/home/huahua/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/home/huahua/.m2/repository/org/springframework/spring-core/5.1.3.relea/spring-core-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-jcl/5.1.3.relea/spring-jcl-5.1.3.relea.jar:/home/huahua/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/home/huahua/.m2/repository/org/projectlombok/lombok/1.18.4/lombok-1.18.4.jar com.feng.spring.springeventmain
17:54:05.347 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/testapplicationlistener.class]
17:54:05.352 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/testapplicationlistener2.class]
17:54:05.353 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/testapplicationlistener3.class]
17:54:05.353 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/testapplicationlistenercopy.class]
17:54:05.358 [main] debug org.springframework.context.annotation.annotationconfigapplicationcontext – refreshing org.springframework.context.annotation.annotationconfigapplicationcontext@64b8f8f4
17:54:05.380 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalconfigurationannotationprocessor’
17:54:05.438 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerprocessor’
17:54:05.440 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerfactory’
17:54:05.443 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalautowiredannotationprocessor’
17:54:05.444 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalcommonannotationprocessor’
17:54:05.451 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘testapplicationlistener’
17:54:05.466 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘testapplicationlistener2’
17:54:05.470 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘testapplicationlistener3’
17:54:05.471 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘testapplicationlistenercopy’
17:54:05.490 [main] debug org.springframework.context.event.eventlistenermethodprocessor – 1 @eventlistener methods procesd on bean ‘testapplicationlistener2’: {public void com.feng.spring.listener.testapplicationlistener2.onapplicationevent(com.feng.spring.event.testspringevent)=@org.springframework.context.event.eventlistener(condition=, value=[], class=[])}
17:54:05.491 [main] debug org.springframework.context.event.eventlistenermethodprocessor – 1 @eventlistener methods procesd on bean ‘testapplicationlistener3’: {public void com.feng.spring.listener.testapplicationlistener3.onapplicationevent(com.feng.spring.event.testspringevent)=@org.springframework.context.event.eventlistener(condition=, value=[], class=[])}
step2:code is: 10000, message is: ———my spring task event————
step3:code is: 10000, message is: ———my spring task event————
code is: 10000, message is: ———my spring task event————
2:code is: 10000, message is: ———my spring task event————process finished with exit code 0
说明spring事件发布订阅成功。同时使用注解的监听比实现类监听先监听,如果我们需要监听的执行顺序怎么办?比如某些监听器先执行?
上面的示例,其实都是注解或者都是实现类,监听器是没有顺序的。如果我们要实现顺序监听呢?我么需要ordered接口的实现,spring提供的实现或者暴露的实现接口如下
如果需要执行顺序,spring提供smartapplicationlistener与genericapplicationlistener可供选择。
其中genericapplicationlistener,spring官方推荐我们提供adapter实现
/** * extended variant of the standard {@link applicationlistener} interface, * exposing further metadata such as the supported event and source type. * * <p>as of spring framework 4.2, this interface superdes the class-bad * {@link smartapplicationlistener} with full handling of generic event types. * * @author stephane nicoll * @since 4.2 * @e smartapplicationlistener * @e genericapplicationlisteneradapter */
/** * extended variant of the standard {@link applicationlistener} interface, * exposing further metadata such as the supported event and source type. * * <p>as of spring framework 4.2, this interface superdes the class-bad * {@link smartapplicationlistener} with full handling of generic event types. * * @author stephane nicoll * @since 4.2 * @e smartapplicationlistener * @e genericapplicationlisteneradapter */public interface genericapplicationlistener extends applicationlistener<applicationevent>, ordered { /** * determine whether this listener actually supports the given event type. * @param eventtype the event type (never {@code null}) */boolean supportventtype(resolvabletype eventtype); /** * determine whether th六角龙鱼is listener actually supports the given source type. * <p>the default implementation always returns {@code true}. * @param sourcetype the source type, or {@code null} if no source */default boolean supportssourcetype(@nullable class<?> sourcetype) {return true;} /** * determine this listener's order in a t of listeners for the same event. * <p>the default implementation returns {@link #lowest_precedence}. */@overridedefault int getorder() {return lowest_precedence;} }
其实applicationlistener在spring中提供了很多默认实现,其中就有smartapplicationlistener,智能监听器。
下面来试试
*/public interface smartapplicationlistener extends applicationlistener<applicationevent>, ordered { /** * determine whether this listener actually supports the given event type. * @param eventtype the event type (never {@code null}) */ //supportventtype与supportssourcetype同时true,监听器才会执行 //监听器支持的事件类型boolean supportventtype(class<? extends applicationevent> eventtype); /** * determine whether this listener actually supports the given source type. * <p>the default implementation always returns {@code true}. * @param sourcetype the source type, or {@code null} if no source */ //supportventtype与supportssourcetype同时true,监听器才会执行 //监听事件发布的类default boolean supportssourcetype(@nullable class<?> sourcetype) {return true;} /** * determine this listener's order in a t of listeners for the same event. * <p>the default implementation returns {@link #lowest_precedence}. */@overridedefault int get信件order() {return lowest_precedence;} }
3个实现方法。支持的类型,支持的事件类,执行顺序
package com.feng.spring.listener; import com.feng.spring.springeventmain;import com.feng.spring.event.testspringevent;import org.springframework.context.applicationevent;import org.springframework.context.event.smartapplicationlistener;import org.springframework.stereotype.component; @componentpublic class orderedlistener implements smartapplicationlistener { public boolean supportventtype(class<? extends applicationevent> eventtype) { return eventtype== testspringevent.class; } public boolean supportssourcetype(class<?> sourcetype) { return springeventmain.class==sourcetype; } public int getorder() { return 5; } public void onapplicationevent(applicationevent event) { system.out.println("my execute step is 555555555555555555555555555"); }} @componentpublic class orderedlistenercopy implements smartapplicationlistener { public boolean supportventtype(class<? extends applicationevent> eventtype) { return eventtype== testspringevent.class; } public boolean supportssourcetype(class<?> sourcetype) { return springeventmain.class==sourcetype; } public int getorder() { return 6; } public void onapplicationevent(applicationevent event) { system.out.println("my execute step is 6666666666666666666666666666"); }}
同理写2个,执行结果如下:
/software/jdk1.8.0_191/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:46603,suspend=y,rver=n -javaagent:/software/ideaide/lib/rt/debugger-agent.jar -dfile.encoding=utf-8 -classpath /software/jdk1.8.0_191/jre/lib/charts.jar:/softw绿茶餐厅加盟条件are/jdk1.8.0_191/jre/lib/deploy.jar:/software/jdk1.8.0_191/jre/lib/ext/cldrdata.jar:/software/jdk1.8.0_191/jre/lib/ext/dnsns.jar:/software/jdk1.8.0_191/jre/lib/ext/jaccess.jar:/software/jdk1.8.0_191/jre/lib/ext/jfxrt.jar:/software/jdk1.8.0_191/jre/lib/ext/localedata.jar:/software/jdk1.8.0_191/jre/lib/ext/nashorn.jar:/software/jdk1.8.0_191/jre/lib/ext/sunec.jar:/software/jdk1.8.0_191/jre/lib/ext/sunjce_provider.jar:/software/jdk1.8.0_191/jre/lib/ext/sunpkcs11.jar:/software/jdk1.8.0_191/jre/lib/ext/zipfs.jar:/software/jdk1.8.0_191/jre/lib/javaws.jar:/software/jdk1.8.0_191/jre/lib/jce.jar:/software/jdk1.8.0_191/jre/lib/jfr.jar:/software/jdk1.8.0_191/jre/lib/jfxswt.jar:/software/jdk1.8.0_191/jre/lib/js.jar:/software/jdk1.8.0_191/jre/lib/management-agent.jar:/software/jdk1.8.0_191/jre/lib/plugin.jar:/software/jdk1.8.0_191/jre/lib/resources.jar:/software/jdk1.8.0_191/jre/lib/rt.jar:/home/huahua/ideaprojects/feng/spring-event/target/class:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.1.relea/spring-boot-starter-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot/2.1.1.relea/spring-boot-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-context/5.1.3.relea/spring-context-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-aop/5.1.3.relea/spring-aop-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-beans/5.1.3.relea/spring-beans-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-expression/5.1.3.relea/spring-expression-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.relea/spring-boot-autoconfigure-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.1.relea/spring-boot-starter-logging-2.1.1.relea.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/home/huahua/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.1/log4j-to-slf4j-2.11.1.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar:/home/huahua/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/home/huahua/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/home/huahua/.m2/repository/org/springframework/spring-core/5.1.3.relea/spring-core-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-jcl/5.1.3.relea/spring-jcl-5.1.3.relea.jar:/home/huahua/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/home/huahua/.m2/repository/org/projectlombok/lombok/1.18.4/lombok-1.18.4.jar:/software/ideaide/lib/idea_rt.jar com.feng.spring.springeventmain
connected to the target vm, address: ‘127.0.0.1:46603’, transport: ‘socket’
18:37:51.002 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/orderedlistener.class]
18:37:51.009 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/orderedlistenercopy.class]
18:37:51.017 [main] debug org.springframework.context.annotation.annotationconfigapplicationcontext – refreshing org.springframework.context.annotation.annotationconfigapplicationcontext@37d31475
18:37:51.055 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalconfigurationannotationprocessor’
18:37:51.129 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerprocessor’
18:37:51.132 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerfactory’
18:37:51.135 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalautowiredannotationprocessor’
18:37:51.136 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalcommonannotationprocessor’
18:37:51.145 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘orderedlistener’
18:37:51.154 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘orderedlistenercopy’
my execute step is 555555555555555555555555555
my execute step is 6666666666666666666666666666
disconnected from the target vm, address: ‘127.0.0.1:46603’, transport: ‘socket’process finished with exit code 0
实现了顺序的监听。
spring使用threadpooltaskexecutor来执行异步任务,其实就是schedulingtaskexecutor,使用@enableasync注解@async注解实现异步监听事件的调用
我们来试试
package com.feng.spring.config; import org.springframework.context.annotation.bean;import org.springframework.context.annotation.configuration;import org.springframework.scheduling.concurrent.threadpooltaskexecutor; import java.util.concurrent.executor;import java.util.concurrent.threadfactory;import java.util.concurrent.atomic.atomicinteger; @configurationpublic class asyncconfig { @bean public executor initexecutor(){ threadpooltaskexecutor executor = new threadpooltaskexecutor(); //定制线程名称,还可以定制线程group executor.tthreadfactory(new threadfactory() { private final atomicinteger threadnumber = new atomicinteger(1); @override public thread newthread(runnable r) { thread t = new thread(thread.currentthread().getthreadgroup(), r, "async-eventlistener-" + threadnumber.getandincrement(), 0); return t; } }); executor.tcorepoolsize(10); executor.tmaxpoolsize(20); executor.tkeepaliveconds(5); executor.tqueuecapacity(100);// executor.trejectedexecutionhandler(null); return executor; }}
@enableasync@componentpublic class testapplicationlistener implements applicationlistener<testspringevent> { @async public void onapplicationevent(testspringevent event) { system.out.println("code is:\t" + event.getcode() + ",\tmessage is:\t" + event.getmessage()); //通过线程group/名称区别 system.out.println(thread.currentthread().getthreadgroup()+ "/" +thread.currentthread().getname()); }}
执行结果:
/software/jdk1.8.0_191/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44287,suspend=y,rver=n -javaagent:/software/ideaide/lib/rt/debugger-agent.jar -dfile.encoding=utf-8 -classpath /software/jdk1.8.0_191/jre/lib/charts.jar:/software/jdk1.8.0_191/jre/lib/deploy.jar:/software/jdk1.8.0_191/jre/lib/ext/cldrdata.jar:/software/jdk1.8.0_191/jre/lib/ext/dnsns.jar:/software/jdk1.8.0_191/jre/lib/ext/jaccess.jar:/software/jdk1.8.0_191/jre/lib/ext/jfxrt.jar:/software/jdk1.8.0_191/jre/lib/ext/localedata.jar:/software/jdk1.8.0_191/jre/lib/ext/nashorn.jar:/software/jdk1.8.0_191/jre/lib/ext/sunec.jar:/software/jdk1.8.0_191/jre/lib/ext/sunjce_provider.jar:/software/jdk1.8.0_191/jre/lib/ext/sunpkcs11.jar:/software/jdk1.8.0_191/jre/lib/ext/zipfs.jar:/software/jdk1.8.0_191/jre/lib/javaws.jar:/software/jdk1.8.0_191/jre/lib/jce.jar:/software/jdk1.8.0_191/jre/lib/jfr.jar:/software/jdk1.8.0_191/jre/lib/jfxswt.jar:/software/jdk1.8.0_191/jre/lib/js.jar:/software/jdk1.8.0_191/jre/lib/management-agent.jar:/software/jdk1.8.0_191/jre/lib/plugin.jar:/software/jdk1.8.0_191/jre/lib/resources.jar:/software/jdk1.8.0_191/jre/lib/rt.jar:/home/huahua/ideaprojects/feng/spring-event/target/class:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.1.relea/spring-boot-starter-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot/2.1.1.relea/spring-boot-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-context/5.1.3.relea/spring-context-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-aop/5.1.3.relea/spring-aop-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-beans/5.1.3.relea/spring-beans-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-expression/5.1.3.relea/spring-expression-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.1.relea/spring-boot-autoconfigure-2.1.1.relea.jar:/home/huahua/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.1.relea/spring-boot-starter-logging-2.1.1.relea.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/home/huahua/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/home/huahua/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.1/log4j-to-slf4j-2.11.1.jar:/home/huahua/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar:/home/huahua/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:/home/huahua/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/home/huahua/.m2/repository/org/springframework/spring-core/5.1.3.relea/spring-core-5.1.3.relea.jar:/home/huahua/.m2/repository/org/springframework/spring-jcl/5.1.3.relea/spring-jcl-5.1.3.relea.jar:/home/huahua/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/home/huahua/.m2/repository/org/projectlombok/lombok/1.18.4/lombok-1.18.4.jar:/software/ideaide/lib/idea_rt.jgrass可数吗ar com.feng.spring.springeventmain
connected to the target vm, address: ‘127.0.0.1:44287’, transport: ‘socket’
19:08:24.692 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/config/asyncconfig.class]
19:08:24.730 [main] debug org.springframework.context.annotation.classpathbeandefinitionscanner – identified candidate component class: file [/home/huahua/ideaprojects/feng/spring-event/target/class/com/feng/spring/listener/testapplicationlistener.class]
19:08:24.741 [main] debug org.springframework.context.annotation.annotationconfigapplicationcontext – refreshing org.springframework.context.annotation.annotationconfigapplicationcontext@37d31475
19:08:24.782 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalconfigurationannotationprocessor’
19:08:25.091 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerprocessor’
19:08:25.094 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.event.internaleventlistenerfactory’
19:08:25.099 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalautowiredannotationprocessor’
19:08:25.100 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalcommonannotationprocessor’
19:08:25.106 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.context.annotation.internalasyncannotationprocessor’
19:08:25.109 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘org.springframework.scheduling.annotation.proxyasyncconfiguration’
19:08:25.252 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘asyncconfig’
19:08:25.261 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘testapplicationlistener’
19:08:25.299 [main] debug org.springframework.beans.factory.support.defaultlistablebeanfactory – creating shared instance of singleton bean ‘initexecutor’
19:08:25.330 [main] info org.springframework.scheduling.concurrent.threadpooltaskexecutor – initializing executorrvice ‘initexecutor’
code is: 10000, message is: ———my spring task event————
java.lang.threadgroup[name=main,maxpri=10]/async-eventlistener-1
看线程名称,已经异步执行了
[name=main,maxpri=10]/async-eventlistener-1
spring的事件通知demo已经完成,如果需要详细的spring事件从发布到订阅的过程,需要跟踪spring的applicationcontext的publishevent的过程,其实spring的applicationcontext的启动的过程中也定义了很详细的事件,使用intellij idea分析,如下:
spring事件通知的本质:生产者-消费者,体现了设计模式的观察者模式。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-04 07:47:21,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/5f7c0e9e6fd3cc28a95408bcd13cfb4e.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Spring事件发布监听,顺序监听,异步监听方式.doc
本文 PDF 下载地址:Spring事件发布监听,顺序监听,异步监听方式.pdf
留言与评论(共有 0 条评论) |