您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Spring的事件發(fā)布與監(jiān)聽方式是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
主要代碼在org.springframework.context
,org.springframework.context.event
包中
事件發(fā)布與監(jiān)聽主要包含以下角色:
事件:ApplicationEvent
事件監(jiān)聽器:ApplicationListener
SmartApplicationListener
GenericApplicationListener
事件發(fā)布器:ApplicationEventPublisher
事件廣播器:ApplicationEventMulticaster
引入ApplicationListener
有兩種方式:
spring spi
手動(dòng)注入bean
手動(dòng)注入bean有兩種方式:
類上注解@Component
等注解+實(shí)現(xiàn)ApplicationListener
接口
類上注解@Component
等注解+方法上注解@EventListener
案例如下:
// bean注入方式一,實(shí)現(xiàn)ApplicationListener+@Component注入bean @Component public class HelloEventListener implements SmartApplicationListener { @Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return false; } @Override public void onApplicationEvent(ApplicationEvent event) { } } // bean注入方式二,@EventListener+@Component @Component public class Test { @EventListener public void listen(Object obj){ System.out.println("listening"); } @EventListener(classes={ApplicationEvent.class},condition="springEL") public void listen(ApplicationEvent event){ System.out.println("listening"); } }
關(guān)于@EventListener
注解方法注入是通過EventListenerMethodProcessor
的一個(gè)SmartInitializingSingleton
,同時(shí)該類也是一個(gè)BeanFactoryPostProcessor
,但掃描@EventListener
方法和注入邏輯不在該接口的postProcess
方法中,而是SmartInitializingSingleton
接口的afterSingletonsInstantiated
方法。
關(guān)于SmartInitializingSingleton
的接口作用注釋如下:
Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap. This interface can be implemented by singleton beans in order to perform some initialization after the regular singleton instantiation algorithm, avoiding side effects with accidental early initialization (e.g. from ListableBeanFactory.getBeansOfType calls). In that sense, it is an alternative to InitializingBean which gets triggered right at the end of a bean’s local construction phase.
看到其作用和 InitializingBean
類似,用于構(gòu)造函數(shù)后的初始化操作,不過該接口是所有bean被創(chuàng)建之后被調(diào)用。在所有 bean的構(gòu)造方法、初始化(@PostConstruct
、InitializingBean
)、BeanPostProcessor
都執(zhí)行完畢后再執(zhí)行該接口方法,注意是所有bean都執(zhí)行完這些方法。
Invoked right at the end of the singleton pre-instantiation phase, with a guarantee that all regular singleton beans have been created already.
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor { // 負(fù)責(zé)設(shè)置EventListenerFactory @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 回調(diào)beanFactory賦值 this.beanFactory = beanFactory; // 拿到所有的EventListenerFactory Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false); List<EventListenerFactory> factories = new ArrayList<>(beans.values()); AnnotationAwareOrderComparator.sort(factories); // 設(shè)置eventListenerFactories this.eventListenerFactories = factories; } @Override public void afterSingletonsInstantiated() { ... processBean(beanName, type); ... } private void processBean(final String beanName, final Class<?> targetType) { if ( // 不包含@EventListener的類的備忘錄是否有該類型 !this.nonAnnotatedClasses.contains(targetType) && // 該類型的type, method or field 是否能被注解@EventListener AnnotationUtils.isCandidateClass(targetType, EventListener.class) && // 不能是org.springframework開頭的類,或者被注解了@Component,注意是或者 !isSpringContainerClass(targetType) ) { // 提取所有的方法 Map<Method, EventListener> annotatedMethods = null; try { annotatedMethods = MethodIntrospector.selectMethods(targetType, (MethodIntrospector.MetadataLookup<EventListener>) method -> AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class)); } ... if (CollectionUtils.isEmpty(annotatedMethods)) { // 備忘錄,加入已掃描的沒有注解@EventListener的類 this.nonAnnotatedClasses.add(targetType); ... } 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) { if (factory.supportsMethod(method)) { Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName)); // 生成ApplicationListener ApplicationListener<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse); if (applicationListener instanceof ApplicationListenerMethodAdapter) { ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator); } context.addApplicationListener(applicationListener); break; } ...
ApplicationListener
監(jiān)聽到事件后的執(zhí)行是同步過程,如果需要異步,可搭配@Async+@EventListener
spring-tx
包下提供TransactionalApplicationListener
接口和@TransactionalEventListener
注解。
TransactionalApplicationListener接口:An ApplicationListener that is invoked according to a TransactionPhase. NOTE: Transactional event listeners only work with thread-bound transactions managed by a PlatformTransactionManager.
“Spring的事件發(fā)布與監(jiān)聽方式是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。