您好,登录后才能下订单哦!
本篇内容介绍了“Spring的事件发布与监听方式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
主要代码在org.springframework.context
,org.springframework.context.event
包中
事件发布与监听主要包含以下角色:
事件:ApplicationEvent
事件监听器:ApplicationListener
SmartApplicationListener
GenericApplicationListener
事件发布器:ApplicationEventPublisher
事件广播器:ApplicationEventMulticaster
引入ApplicationListener
有两种方式:
spring spi
手动注入bean
手动注入bean有两种方式:
类上注解@Component
等注解+实现ApplicationListener
接口
类上注解@Component
等注解+方法上注解@EventListener
案例如下:
// bean注入方式一,实现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"); } }
关于@EventListener
注解方法注入是通过EventListenerMethodProcessor
的一个SmartInitializingSingleton
,同时该类也是一个BeanFactoryPostProcessor
,但扫描@EventListener
方法和注入逻辑不在该接口的postProcess
方法中,而是SmartInitializingSingleton
接口的afterSingletonsInstantiated
方法。
关于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
类似,用于构造函数后的初始化操作,不过该接口是所有bean被创建之后被调用。在所有 bean的构造方法、初始化(@PostConstruct
、InitializingBean
)、BeanPostProcessor
都执行完毕后再执行该接口方法,注意是所有bean都执行完这些方法。
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 { // 负责设置EventListenerFactory @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 回调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); // 设置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
监听到事件后的执行是同步过程,如果需要异步,可搭配@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的事件发布与监听方式是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。