InitializingBean和ApplicationListenerContextRefreshedEvent的用法和区别

本文主要是介绍InitializingBean和ApplicationListenerContextRefreshedEvent的用法和区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.InitializingBean的时机是初始化bean的时候,而ApplicationListener<ContextRefreshedEvent>是在bean初始化完成后。(必须要等到所有的bean都被处理完成之后再进行,必须用InitializingBean

也就是先有InitializingBean,后有ApplicationListener<ContextRefreshedEvent>

InitializingBean初始化bean的顺序是默认构造器->afterPropertiesSet方法

 

2.InitializingBean:作用

spring初始化bean的时候,如果bean实现了InitializingBean接口,

当执行完默认的构造函数之后,就会调用该类实现afterPropertiesSet方法

会自动调用afterPropertiesSet方法。

spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。

 

<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>

 

import org.springframework.beans.factory.InitializingBean;

public class TestInitializingBean implements InitializingBean{

 

    @Override

    public void afterPropertiesSet() throws Exception {

        System.out.println("ceshi InitializingBean");       

    }

    public void testInit(){

        System.out.println("ceshi init-method");       

    }

没有实现InitializingBean这个接口,直接进行init-method中的,也可以。

<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>

import org.springframework.beans.factory.InitializingBean;

public class TestInitializingBean {

    public void testInit(){

        System.out.println("ceshi init-method");       

    }

 

3.ApplicationListener<ContextRefreshedEvent>用法:

一个最简单的方式就是,让我们的bean实现ApplicationListener接口,这样当发布事件时,springioc容器就会以容器的实例对象作为事件源类,并从中找到事件的监听者,此时ApplicationListener接口实例中的onApplicationEvent(ApplicationEvent event)方法就会被调用,我们的逻辑代码就会写在此处。这样我们的目的就达到了。

@Override 

      public void onApplicationEvent(ContextRefreshedEvent event) { 

        if(event.getApplicationContext().getParent() == null){//root application context 没有parent,他就是老大

             //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。 

        } 

      } 

使用这个必须要有:if(event.getApplicationContext().getParent() == null)或者if(event.getApplicationContext().getParent() != null)这行,代码逻辑必须在这个里面,否不行。非null判断是springmvc管理;null值判断,那里面的逻辑就是spring管理。

 

就需要实现ApplicationListener<ContextRefreshedEvent>接口进行操作,同时,

 

applicationontext和使用MVC之后的webApplicationontext会两次调用上面的方法,如何区分这个两种容器呢?

 

但是这个时候,会存在一个问题,在web 项目中(spring mvc),系统会存在两个容器,一个是root application context ,另一个就是我们自己的 projectName-servlet context(作为root application context的子容器)。

 

这种情况下,就会造成onApplicationEvent方法被执行两次。为了避免上面提到的问题,我们可以只在root application context初始化完成后调用逻辑代码,其他的容器的初始化完成,则不做任何处理,修改后代码

 

 @Override 

      public void onApplicationEvent(ContextRefreshedEvent event) { 

        if(event.getApplicationContext().getParent() == null){//root application context 没有parent,他就是老大

             //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。 

        } 

 

      } 

 

上面是网上的大部分说法,但是,我在做项目时,我想着为啥不能进行非null值判断呢,那样的话就是projectName-servlet context容器进行管理了,也是可以的呀,后来我一想,原来我的问题实际上是SpringSpringMVC父子 容器的问题,就看这个想要谁管理你的逻辑代码,就用哪个容器,非null

 

判断是springmvc管理;null值判断,那里面的逻辑就是spring管理。这就要求我们必须再看看俩种容器

 

的区别,在这里由于版面问题,不再详述,但是,我会在下一篇文章详细介绍俩种容器的区别与使用,

4.ApplicationListener有自己的用法

所有的类实现ApplicationListener实现这个接口,然后在事件源中调用publishEvent()方法就可以了。(事件三要素)

ApplicationListener,只要有publishEvent,实现ApplicationListener就可以都监听到,其他情况也可以的。比如EventListenter等都可以的。

5.事件:

事件三要素:事件对象、事件监听者、事件源

其实,实现了ApplicationListener这个接口的类就是事件监听者(onApplicationEvent(ApplicationEvent event))。调用了publishEvent(Event event)方法的就是事件源,这个方法中的event就是事件对象。也可以这么说,事件对象和事件监听者就是一个。

IOC的容器的启动过程,当所有的bean都已经处理完成之后,spring ioc容器会有一个发布事件的动作。

 

监听者模式可以自己实现,模仿spring的模式。如果不行,就实现spring监听者接口,抽象出一个模型,然后也就是类似模仿了,就可以实现了。

 

附加结论:监听器、拦截器、过滤器、异步、aop都是横向对代码进行操作,对代码无侵入的操作。

这篇关于InitializingBean和ApplicationListenerContextRefreshedEvent的用法和区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146639

相关文章

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`

Python中json文件和jsonl文件的区别小结

《Python中json文件和jsonl文件的区别小结》本文主要介绍了JSON和JSONL两种文件格式的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 众所周知,jsON 文件是使用php JSON(JavaScripythonpt Object No

oracle中exists和not exists用法举例详解

《oracle中exists和notexists用法举例详解》:本文主要介绍oracle中exists和notexists用法的相关资料,EXISTS用于检测子查询是否返回任何行,而NOTE... 目录基本概念:举例语法pub_name总结 exists (sql 返回结果集为真)not exists (s

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

Springboot中Jackson用法详解

《Springboot中Jackson用法详解》Springboot自带默认json解析Jackson,可以在不引入其他json解析包情况下,解析json字段,下面我们就来聊聊Springboot中J... 目录前言Jackson用法将对象解析为json字符串将json解析为对象将json文件转换为json

python中json.dumps和json.dump区别

《python中json.dumps和json.dump区别》json.dumps将Python对象序列化为JSON字符串,json.dump直接将Python对象序列化写入文件,本文就来介绍一下两个... 目录1、json.dumps和json.dump的区别2、使用 json.dumps() 然后写入文

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

bytes.split的用法和注意事项

当然,我很乐意详细介绍 bytes.Split 的用法和注意事项。这个函数是 Go 标准库中 bytes 包的一个重要组成部分,用于分割字节切片。 基本用法 bytes.Split 的函数签名如下: func Split(s, sep []byte) [][]byte s 是要分割的字节切片sep 是用作分隔符的字节切片返回值是一个二维字节切片,包含分割后的结果 基本使用示例: pa