springboot2 利用ApplicationListener启动加载字典表

简介:

ApplicationListener在使用过程中可以监听某一事件的发生,可以做出相应的处理,这个方式不常用,但是在特殊情况下面还是有用的。

使用场景:

在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。这个时候我们就可以使用Spring提供的ApplicationListener来进行操作。

用法

本文以在Spring boot下的使用为例来进行说明。首先,需要实现ApplicationListener接口并实现onApplicationEvent方法。把需要处理的操作放在onApplicationEvent中进行处理:

二次调用问题

此处使用Spring boot来进行操作,没有出现二次调用的问题。在使用传统的application.xml和project-servlet.xml配置中会出现二次调用的问题。主要原因是初始化root容器之后,会初始化project-servlet.xml对应的子容器。我们需要的是只执行一遍即可。那么上面打印父容器的代码用来进行判断排除子容器即可。在业务处理之前添加如下判断:

if(contextRefreshedEvent.getApplicationContext().getParent() != null){
            return;
}if(contextRefreshedEvent.getApplicationContext().getParent() != null){
            return;
}

这样其他容器的初始化就会直接返回,而父容器(Parent为null的容器)启动时将会执行相应的业务操作。

关联知识

在spring中InitializingBean接口也提供了类似的功能,只不过它进行操作的时机是在所有bean都被实例化之后才进行调用。根据不同的业务场景和需求,可选择不同的方案来实现。

 

springboot初始化加载字典源码如下:

1、pom文件



  4.0.0
  
    org.springframework.boot
    spring-boot-starter-parent
    2.1.7.RELEASE
     
  
  com.mqm501
  springboot-init
  0.0.1-SNAPSHOT
  springboot-init
  Demo project for Spring Boot

  
    1.8
  

  
    
      org.springframework.boot
      spring-boot-starter-web
    
    
      org.mybatis.spring.boot
      mybatis-spring-boot-starter
      2.1.0
    

    
      mysql
      mysql-connector-java
      runtime
    
    
      org.springframework.boot
      spring-boot-starter-test
      test
    
    
      com.alibaba
      druid
      1.1.0
    
    
      org.mybatis.spring.boot
      mybatis-spring-boot-starter
      2.1.0
    
  

  
    
      
        org.springframework.boot
        spring-boot-maven-plugin
      
    
  


2、字典表配置文件:

{
  "age_segment":{
    "0":"0-17",
    "1":"18-25",
    "2":"26-35",
    "3":"36-45",
    "4":"46-55",
    "5":"56-"
  },
  "sex_type":{
    "0":"男",
    "1":"女",
    "2":"不详"
  },
  "profession_type":{
    "1":"一级",
    "2":"二级",
    "3":"三级",
    "4":"四级",
    "5":"五级",
    "6":"六级",
    "7":"其他"
  },
  "marry_type":{
    "0":"未婚",
    "1":"已婚",
    "2":"丧偶",
    "3":"分居",
    "4":"再婚",
    "5":"同居",
    "6":"离婚",
    "9":"其他"
  },
  "buyer_flag":{
    "1":"是",
    "2":"否"
  }
}

3、读取字典配置文件

package com.hlt.sundata.httpglobal.init;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;

/**
 * Project: sundata Package: com.hlt.sundata.httpglobal.bean
 * 

Create Time: 2019年08月30日 00:56

*

@author: qingmei.meng

*

Description:

**/ @Service("dictInit") public class DictInit { /**存放系统参数*/ public static HashMap dictMap = new HashMap(); /**参数初始化工作*/ public void start() { injectDictConfig(); } /**读取字典表 */ private void injectDictConfig() { System.out.println("-------injectDictConfigByDb start-------------------"); try { String filename = "static/data/dic.json"; FileInputStream inputStream = null; File file = new File(filename); if (!file.exists()) { // 如果同级目录没有,则去config下面找 file = new File("config/"+filename); } Resource resource = new FileSystemResource(file); if (!resource.exists()) { //config目录下还是找不到,那就直接用classpath下的 file = ResourceUtils.getFile("classpath:"+filename); } inputStream = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charsets.UTF_8)); String var = FileCopyUtils.copyToString(reader); String newVar = var.replaceAll("\\s*",""); inputStream.close(); System.out.println(newVar); ObjectMapper mapper = new ObjectMapper(); try { dictMap = mapper.readValue(newVar, new TypeReference>() {}); } catch (Exception e) { e.printStackTrace(); System.out.println("-------injectDictConfig to json error-------------------"); } } catch (IOException e) { e.printStackTrace(); System.out.println("-------injectDictConfig file error-------------------"); } System.out.println("-------injectDictConfig success-------------------"); } }

4、springboot初始化加载

package com.hlt.sundata.httpglobal.init;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

/**
 * Project: sundata Package: com.hlt.sundata.httpglobal.util
 * 

Create Time: 2019年08月30日 00:53

*

@author: qingmei.meng

*

Description:

**/ @Component("BeanDefineConfigue") public class StartLoader implements ApplicationListener { @Autowired private DictInit dictInit; //当一个ApplicationContext被初始化或刷新触发 @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("START:spring初始化开始======================>"); if (event.getApplicationContext().getParent() == null) {//root application context 没有parent,他就是老大. System.out.println("启动projectInit的start方法进行参数的初始化======================>"); dictInit.start(); } else { //为什么会执行两次:请参考博文:http://www.cnblogs.com/yucongblog/p/5437744.html System.out.println("spring初始化时,执行onApplicationEvent:event.getApplicationContext().getParent() != null======================>"); } System.out.println("spring初始化完毕======================>"); } }

5、启动后成功加载

START:spring初始化开始======================>
启动projectInit的start方法进行参数的初始化======================>
-------injectDictConfigByDb start-------------------
{"age_segment":{"0":"0-17","1":"18-25","2":"26-35","3":"36-45","4":"46-55","5":"56-"},"sex_type":{"0":"男","1":"女","2":"不详"},"profession_type":{"1":"一级","2":"二级","3":"三级","4":"四级","5":"五级","6":"六级","7":"其他"},"marry_type":{"0":"未婚","1":"已婚","2":"丧偶","3":"分居","4":"再婚","5":"同居","6":"离婚","9":"其他"},"buyer_flag":{"1":"是","2":"否"}}
-------injectDictConfig success-------------------
spring初始化完毕======================>

 

你可能感兴趣的:(SpringBoot,初始化字典)