首页 > 其他分享 >spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)

spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)

时间:2023-05-06 16:01:16浏览次数:45  
标签:初始化 ContextRefreshedEvent spring context import event 加载


关键字:spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)

应用场景:很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用了其他类(可能是更复杂的关联),所以当我们去使用这个类做事情时发现包空指针错误,这是因为我们这个类有可能已经初始化完成,但是引用的其他类不一定初始化完成,所以发生了空指针错误,解决方案如下:

1、写一个类继承spring的ApplicationListener监听,并监控ContextRefreshedEvent事件(容易初始化完成事件)

2、定义简单的bean:<bean id="beanDefineConfigue" class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>

或者直接使用@Component("BeanDefineConfigue")注解方式


完整的类如下:

package com.creatar.portal.webservice; 


import org.springframework.context.ApplicationListener; 

import org.springframework.context.event.ContextRefreshedEvent; 

import org.springframework.stereotype.Component; 


@Component("BeanDefineConfigue") 

public class BeanDefineConfigue implements 

 ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent为初始化完毕事件,spring还有很多事件可以利用 


// @Autowired 

// private IRoleDao roleDao; 



 /** 

 * 当一个ApplicationContext被初始化或刷新触发 

 */ 

 @Override 

 public void onApplicationEvent(ContextRefreshedEvent event) { 

// roleDao.getUserList();//spring容器初始化完毕加载用户列表到内存 

 System.out.println("spring容易初始化完毕================================================"); 

 } 


}




或者使用xml配置方式(非注解),简单配置个bean即可

<bean id="beanDefineConfigue" class="com.creatar.portal.webservice.BeanDefineConfigue"></bean>



其他定义方式:

完整的类如下:

package com.creatar.portal.webservice; 


import java.util.ArrayList; 

import java.util.List; 


import org.springframework.context.ApplicationEvent; 

import org.springframework.context.ApplicationListener; 

import org.springframework.context.event.ContextRefreshedEvent; 

import org.springframework.stereotype.Component; 


@Component("BeanDefineConfigue2") 

public class BeanDefineConfigue2 implements ApplicationListener<ApplicationEvent> { 


 List<String> list = new ArrayList<String>(); 


 /** 

 * 当一个ApplicationContext被初始化或刷新触发 

 */ 

 @Override 

 public void onApplicationEvent(ApplicationEvent event) { 

 if (event instanceof ContextRefreshedEvent) { 

 System.out.println("spring容易初始化完毕================================================888"); 

 } 


 } 

}



spring其他事件:

spring中已经内置的几种事件:

ContextClosedEvent 、ContextRefreshedEvent 、ContextStartedEvent 、ContextStoppedEvent 、RequestHandleEvent


[color=red]后续研究:[/color]
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){//[color=red]root application context 没有parent,他就是老大[/color]. 

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

 } 

 }




[color=red]后续发现加上以上判断还是能执行两次,不加的话三次,最终研究结果使用以下判断更加准确:event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")[/color]

标签:初始化,ContextRefreshedEvent,spring,context,import,event,加载
From: https://blog.51cto.com/u_7450530/6250462

相关文章

  • SpringBoot 操作 MongoDB 新增和查询
    MongoDBJAVA新增+查询上接SpringBoot整合MongoDB,记一下MongoDB的CRUD方法。Create新增使用MongoRepository方式的新增非常简单,之前的整合中已经尝试过,这里再总结一下:首先需要有对应的实体类对象:@Data@AllArgsConstructor@NoArgsConstructor@ToStringpublicc......
  • 聊聊关于,SpringBoot写后端接口
    前言:一个后端接口大致分为四个部分组成:接口地址(url)、接口请求方式(get、post等)、请求数据(request)、响应数据(response)。如何构建这几个部分每个公司要求都不同,没有什么“一定是最好的”标准,但一个优秀的后端接口和一个糟糕的后端接口对比起来差异还是蛮大的,其中最重要的关键点就是......
  • Spring17_JdbcTemplate基本使用12
    一、概述(了解)JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的JdbcAPI对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的 RedisTemplate,操作消息队列的JmsTemplate等等。......
  • spring cloud gradle mybatis
    一、引入依赖在build.gradle文件中的dependencies的对象中引入依赖implementation'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'二、配置数据库及mybatis在application.yml文件中配置数据库spring:datasource:url:jdbc:mysql://192.168.0.1:3306/dbName......
  • spring cloud 配置 redis、定义redis工具类
    一、引入redis工具依赖在build.gradle文件中的dependencies的对象中引入依赖compile'org.springframework.boot:spring-boot-starter-data-redis:2.1.5.RELEASE'二、application.xml配置redisspringredis:database:#Redis数据库索引(默认为0)host:......
  • spring cloud、gradle、父子项目、微服务框架搭建---搭建父子级多模块项目,并注册到Eu
    一、新建一个父级gradl模块1.在桌面或新建文件里面,右键,打开IDEA选择Flie>NEW>Module选择Gradle,选择ModuleSDK1.8,选择Java创建完成后,idea中会多出一个项目,如下图示例然后直接关闭当前idea,进入刚才创建好的文件下,再次打开项目可以直接删除src目录二、新建子级gradl模......
  • SpringBoot 自动扫描第三方包及spring.factories失效的问题
    为什么会找不到Spring依赖注入就是要让spring找到要注入的类并且识别到了@Component、@Service等注解。1.当在开发的第三方包里写明了@Component、@Service等等2.引入了包,不论第三方库的引入,还是本地jar。总之是要引入到工程的这时候还加入不到IOC容器,那就说明Spri......
  • SpringWeb Flux入门
    新建项目,加入依赖:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframew......
  • Google推荐的图片加载库Glide介绍
    Fresco以及我们今天的主角Glide。它们各有千秋,不能评定谁一定比谁好,只能说哪一个更适合你。我的理解下面我来谈一下个人对这些图片加载库的理解,如有错误,还望指教。UniversalImageLoader:一个强大的图片加载库,包含各种各样的配置,最老牌,使用也最广泛。Picasso:Square出品,必属精品......
  • Android开发:使用Glide动态加载圆形图片和圆角图片
    最新消息,鼎鼎大名的Yelp应用也转投Glide的阵营了,而且Glide在跟Listview的配合起来非常的顺畅,Glide除了配置简单,还可以本地缓存图片,也可以实现Listview图片的提前预加载,使得listview的更加的顺滑,具体可以查看Yelp的那篇博文。但是如果碰到要把加载下来的图片转成圆角或者圆形的图......