欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring的事件發(fā)布與監(jiān)聽方式案例講解

 更新時(shí)間:2023年03月27日 11:16:16   作者:T.Y.Bao  
今天去官網(wǎng)查看spring?boot資料時(shí),在特性中看見了系統(tǒng)的事件及監(jiān)聽章節(jié),所以下面這篇文章主要給大家介紹了關(guān)于SpringBoot事件發(fā)布和監(jiān)聽的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

事件

主要代碼在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)造方法、初始化(@PostConstructInitializingBean)、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

事務(wù)消息監(jiān)聽器

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.

到此這篇關(guān)于Spring的事件發(fā)布與監(jiān)聽方式案例講解的文章就介紹到這了,更多相關(guān)Spring事件發(fā)布與監(jiān)聽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • String轉(zhuǎn)double失去精度問題及解決

    String轉(zhuǎn)double失去精度問題及解決

    這篇文章主要介紹了關(guān)于String轉(zhuǎn)double失去精度問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 詳解Java如何實(shí)現(xiàn)FP-Growth算法

    詳解Java如何實(shí)現(xiàn)FP-Growth算法

    學(xué)校里的實(shí)驗(yàn),要求實(shí)現(xiàn)FP-Growth算法.FP-Growth算法比Apriori算法快很多(但是卻比不上時(shí)間)在網(wǎng)上搜索后發(fā)現(xiàn)Java實(shí)現(xiàn)的FP-Growth算法很少,且大多數(shù)不太能理解):太菜.所以就自己實(shí)現(xiàn)了一下.這篇文章重點(diǎn)介紹一下我的Java實(shí)現(xiàn) ,需要的朋友可以參考下
    2021-06-06
  • Mybatis-Plus邏輯刪除的用法詳解

    Mybatis-Plus邏輯刪除的用法詳解

    這篇文章主要為大家詳細(xì)介紹了Mybatis-Plus 邏輯刪除的用法,文中有詳細(xì)的代碼示例,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-07-07
  • 基于Jackson實(shí)現(xiàn)API接口數(shù)據(jù)脫敏的示例詳解

    基于Jackson實(shí)現(xiàn)API接口數(shù)據(jù)脫敏的示例詳解

    用戶的一些敏感數(shù)據(jù),例如手機(jī)號(hào)、郵箱、身份證等信息,在數(shù)據(jù)庫以明文存儲(chǔ),但在接口返回?cái)?shù)據(jù)給瀏覽器(或三方客戶端)時(shí),希望對(duì)這些敏感數(shù)據(jù)進(jìn)行脫敏,所以本文就給大家介紹以惡如何利用Jackson實(shí)現(xiàn)API接口數(shù)據(jù)脫敏,需要的朋友可以參考下
    2023-08-08
  • 詳解Java中“==”與equals()的區(qū)別

    詳解Java中“==”與equals()的區(qū)別

    這篇文章主要介紹了詳解Java中“==”與equals()的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 為什么 Java 8 中不需要 StringBuilder 拼接字符串

    為什么 Java 8 中不需要 StringBuilder 拼接字符串

    java8中,編輯器對(duì)“+”進(jìn)行了優(yōu)化,默認(rèn)使用StringBuilder進(jìn)行拼接,所以不用顯示的使用StringBuilder了,直接用“+”就可以了。下面我們來詳細(xì)了解一下
    2019-05-05
  • 兩行Javascript代碼生成UUID的方法

    兩行Javascript代碼生成UUID的方法

    這篇文章主要介紹了兩行Javascript代碼生成UUID的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBoot + vue2.0查詢所用功能詳解

    SpringBoot + vue2.0查詢所用功能詳解

    這篇文章主要介紹了SpringBoot + vue2.0查詢所用功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • Java線程池必知必會(huì)知識(shí)點(diǎn)總結(jié)

    Java線程池必知必會(huì)知識(shí)點(diǎn)總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java線程池必知必會(huì)知識(shí)點(diǎn)的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • 淺析Java中對(duì)稱與非對(duì)稱加密算法原理與使用

    淺析Java中對(duì)稱與非對(duì)稱加密算法原理與使用

    密碼學(xué)是研究編制密碼和破譯密碼的技術(shù)科學(xué)。這篇文章主要為大家介紹了Java中對(duì)稱與非對(duì)稱加密算法的原理與使用,感興趣的小伙伴可以了解一下
    2023-03-03

最新評(píng)論