spring启动容器加载成功后执行调用方法

  • 需求: 由于在微服务架构中各服务之间都是通过接口调用来进行交互的,像很多的基础服务,类似字典信息其实并不需每次需要的时候再去请求接口.所以我的想法是每次启动项目的时候,容器初始化完成,就去调用一下基础服务的接口.通过一个本地map来缓存需要的数据.当我需要使用的时候直接从本地缓存中取.下面是具体的代码实现.
  • 在启动类中实现ApplicationListener 接口,重写onApplicationEvent(ApplicationReadyEvent applicationReadyEvent)方法.
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.ComponentScan;

import java.util.Map;

import static com.ykc.flowside.constants.Constants.DISCOUNT_TYPE;
import static com.ykc.flowside.constants.Constants.OPERATOR_INFO;
import static com.ykc.flowside.utils.FeignStaticUtils.getDictInfo;
import static com.ykc.flowside.utils.FeignStaticUtils.getOperatorInfo;

/**
 * @author lisongyu
 * @ClassName com.ykc.flow.FlowSideApplication
 * @description
 * @create 2019年03月25日 16:31
 */
@SpringBootApplication(exclude = {KafkaAutoConfiguration.class})
@ComponentScan(basePackages = "com.ykc")
@Slf4j
@EnableFeignClients
public class FlowSideApplication implements ApplicationListener<ApplicationReadyEvent> {

    public static void main(String[] args) {
        SpringApplication.run(FlowSideApplication.class, args);

    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        try {
            Map<String, DictEntity> dictInfo = getDictInfo();
            log.info("[项目启动时调用g1] 字典数据:{}条", dictInfo.size());
            Map<Integer, OperatorInfo> operatorInfo = getOperatorInfo(null);
            log.info("[项目启动时调用g1] 电站数据:{}条", operatorInfo.size());
            dictInfo.keySet().forEach(k -> DISCOUNT_TYPE.put(k, dictInfo.get(k)));
            operatorInfo.keySet().forEach(k -> OPERATOR_INFO.put(k, operatorInfo.get(k)));
        } catch (Exception e) {
            log.error("[项目启动时调用g1] 发生错误,", e);
        }
    }

}
  • 调用工具类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ykc.config.common.entity.Header;
import com.ykc.config.common.entity.Message;
import com.ykc.config.common.entity.RequestData;
import com.ykc.flowside.entity.base.DictEntity;
import com.ykc.flowside.exception.FlowSideException;
import com.ykc.flowside.feign.IBaseServerFeign;
import com.ykc.flowside.form.flow.OrgForm;
import com.ykc.flowside.vo.GunInfo;
import com.ykc.flowside.vo.OperatorInfo;
import com.ykc.flowside.vo.OrgVO;
import com.ykc.service.RedisService;
import com.ykc.util.CodeHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.ykc.flowside.constants.Constants.FLOW_SIDE;

/**
 * @author lisongyu
 * @ClassName cn.lisongyu.utils.FeignStaticUtils
 * @description
 * @create 2019年04月08日 16:30
 */
@Component
@Slf4j
public class FeignStaticUtils {

  //存放运营商信息
    public static ConcurrentHashMap<Integer, OperatorInfo> OPERATOR_INFO = new ConcurrentHashMap<>();
    //存放字典信息
    public static ConcurrentHashMap<String, DictEntity> DISCOUNT_TYPE = new ConcurrentHashMap<>();

    private static IBaseServerFeign iBaseServerFeign;

    private static RedisService redisService;

    @Autowired
    public FeignStaticUtils(IBaseServerFeign iBaseServerFeign, RedisService redisService) {
        FeignStaticUtils.iBaseServerFeign = iBaseServerFeign;
        FeignStaticUtils.redisService = redisService;
    }

    /**
     * 获取服务费折扣类型
     *
     * @return
     */
    public static Map<String, DictEntity> getDictInfo() {
        //调用G1接口
        RequestData<Object> requestData = new RequestData<>();
        requestData.setHeader(new Header());
        Map<String, List<String>> param = new HashMap<>();
        param.put("types", Collections.singletonList("service_discount_type"));
        requestData.setBody(param);
        Message dictionary = iBaseServerFeign.getDictionary(requestData);
        List<DictEntity> discountTypes = JSONArray.parseArray(JSON.toJSONString(
                (JSON.parseObject(
                        JSON.toJSONString(dictionary.getBody()), Map.class).get("service_discount_type"))),
                DictEntity.class);
        //将字典项转换成map
        return discountTypes.stream().collect(Collectors.toMap(DictEntity::getId, a -> a, (k1, k2) -> k1));
    }

    /**
     * 获取运营商信息
     *
     * @return
     */
    public static Map<Integer, OperatorInfo> getOperatorInfo(Integer operatorId) {
        //调用G1接口 获取运营商信息
        RequestData<Object> requestData = new RequestData<>();
        requestData.setHeader(new Header());
        Map<String, List<String>> param = new HashMap<>();
        if (CodeHelper.isNull(operatorId))
            param.put("idList", Collections.emptyList());
        else
            param.put("idList", Collections.singletonList(String.valueOf(operatorId)));
        requestData.setBody(param);
        Message message = iBaseServerFeign.selectOperatorNameById(requestData);
        List<OperatorInfo> operatorInfos = JSONArray.parseArray(JSON.toJSONString(message.getBody()), OperatorInfo.class);
        //将运营商信息转换成map
        return operatorInfos.stream().collect(Collectors.toMap(OperatorInfo::getStationOperatorId, a -> a, (k1, k2) -> k1));
    }

    /**
     * 模糊查询运营商信息
     *
     * @return
     */
    public static List<Integer> likeByOperatorName(String stationOperatorName) {
        //调用G1接口 模糊查询运营商信息
        try {
            RequestData<Object> requestData = new RequestData<>();
            requestData.setHeader(new Header());
            Map<String, String> param = new HashMap<>();
            param.put("stationOperatorName", stationOperatorName);
            requestData.setBody(param);
            Message message = iBaseServerFeign.likeByOperatorName(requestData);
            List<OperatorInfo> operatorInfos = JSONArray.parseArray(JSON.toJSONString(message.getBody()), OperatorInfo.class);
            return operatorInfos.stream().map(OperatorInfo::getStationOperatorId).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("[调用G1接口 模糊查询运营商信息] 发生错误", e);
            return Collections.singletonList(0);
        }
    }

}
  • 由于在静态类中使用@Autowired注入会默认成null,所以要使用当前类去重新获取一下.

原文地址:https://www.cnblogs.com/lisongyu/p/10790486.html

时间: 2024-11-05 13:36:29

spring启动容器加载成功后执行调用方法的相关文章

spring 容器加载完成后执行某个方法

理论 刚好再开发过程中遇到了要在项目启动后自动开启某个服务,由于使用了spring,我在使用了spring的listener,它有onApplicationEvent()方法,在Spring容器将所有的Bean都初始化完成之后,就会执行该方法. 应用场景:很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用了其他类(可能是更复杂的关联),所以当我们去使用这个类做事情时发现包空指针错误,这是因为我们这个类有可能已经初始化完成,但是引用的其他类不一定初始化完成

springboot框架在容器加载完成之后执行某个方法

问题描述: 想在websocket实现的Handler中执行一些初始化操作,但是初始化操作使用到了@Autowired自动注入的变量,而且是保护类型.第一个想法是放到Handler构造函数中执行,但是@Autowired注入的变量为null,故此方法不可行. 问题解决 解决方法一 在Application启动类中实现ApplicationListener接口,这个接口支持的ApplicationReadyEvent事件在上下文已经准备完毕的时候触发. 代码如下 /* * Copyright 20

PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题

PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题,PageSlider中加入CSS3动画的话,默认只有首屏是从无到有执行动画,其他屏都是显示下页面再执行动画 这就造成其他屏的动画展示效果不好,解决方法,让所有屏的背景可见,但是只要当前屏的元素可见; 上代码: .page { width: 100%; height: 100%; -webkit-backface-visibility: hidden; -webkit-perspective: 1000; div, ul,

js中页面加载完成后执行的几种方式及执行顺序

在js和jquery使用中,经常使用到页面加载完成后执行某一方法.通过整理,大概是五种方式(其中有的只是书写方式不一样). 1:使用jQuery的$(function){}; 2:使用jquery的$(document).ready(function(){});前两者本质上没有区别,第1种是第2种的简写方式.两个是document加载完成后就执行方法. 3:使用jQuery的$(window).load(function(){}); 4:使用window.onload = function(){

Android下设置ListView数据加载完成后执行layoutanimation

今天使用android的volley框架写了一个简单的网络天气获取的demo. 承载数据的空间是ListView 因为是网络加载,必然先要设置ListView的默认数据,我设置的就是那个Loading... 然后从网络获取到数据后,再解析,然后更新到adapter,然后notifyDataSetChanged更新数据到ListView. 可是ListView设置了layoutanimation,这样默认的ListView打开后那个Loading执行了动画,当网络数据加载完毕后, layoutan

window.onload在文档加载完成后执行

验证a .b两点疑惑: a.<script src="./main.js"></script>中的window.onload是在html全部加载完了才执行,还是其在html中所处位置之前的加载完就执行? b. <script src="./main.js"></script>中window.onload有和没有 的区别是什么? 结论: a. answer:在html全部加载完了才执行. b. answer:区别就是,w

ExtJS中关于分页加载数据后执行一个回调函数的问题

前几天,一个项目中有用到ExtJS.之前修改的时候,只是在Store Load的时候执行一个回调,这个会导致翻页的时候,没有执行这个回调,而这个回调做的恰好是一些数据的格式验证不可或缺的. 被这个问题困扰了很久,也查了很多的关于ExtJs Store的应用和API,最终找到了一个解决的办法,其实很简单,就是在Store里面添加一个load事件的监听. new Ext.data.Store({... listeners: { "load": function (store, operat

在css加载完毕后执行后续代码

最近在写项目的framework,写个JQueryMessageBox的类,以使用jquery ui中的dialog()来显示消息框,为了使方法方便调用,便加入了自动判断页面是否加入了ui.js和ui.css,代码如下: [javascript] view plaincopyprint? //如果没有包含ui.js,则引用 if ($('script[src$=""jquery-ui-1.8.11.custom.min.js""]').length == 0) {{

利用Promise实现数据多个请求加载完成时执行某个方法

在实际开发中常常有些业务的数据是来自多个接口的,因为ajax是异步,这样就导致我们需要判断是否请求到了数据然后在做其他的逻辑,在Promise没有出现之前,通常我们的解决方法是,第一粗暴的改异步为同步,但这样会造成阻塞,异步好像又失去了意义,第二也就是大家常用的解决办法用回调既一个异步执行完成后在执行下一个请求,这样看比第一种要好太多了,但是问题又来了,延迟延迟延迟,请求越多最后的那个请求延迟就会越严重,而且这样请求多了之后逻辑就会变得很乱...痛苦不堪,还好es6带来的Promise正好能解决