spring再tomcat启动后,初始化完成后,自动执行一次某个类,怎么做

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring再tomcat启动后,初始化完成后,自动执行一次某个类,怎么做相关的知识,希望对你有一定的参考价值。

spring再tomcat启动后,初始化完成后,自动执行一次某个类,怎么做
这个类使用了spring的注入,所以要求这个类是受spring管理的
容器启动后,spring加载完毕,然后自动运行一下这个类,怎么做?

明白你的意思了,在tomcat启动完成后,spring启动前执行的操作:这里你可增加一个Listener 类(implements ServletContextListener),然后在web.xml中记得配置一下
<listener>
<listener-class>包名.自定义的Listener</listener-class>
</listener>
第一个解决;
第二个: 新增一个类,通过在类名上注解(@Component)的方式加入spring组件,在方法上增加注解(@PostConstruct);
如果以上还是不能解决你的问题,那你可以换一个思路,如说你要达到什么目的,能不能从目的直接出发;
参考技术A 将你需要自动执行的类实现ApplicationContextAware接口,applicationContext 会被注入进你需要自动执行的类。最后自定义一个servlet在init()方法中初始化该类。servlet在web.xml配置中<load-on-startup>最大值</load-on-startup> 参考技术B 用spring 的quartz本回答被提问者采纳

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,所以要使用当前类去重新获取一下.

以上是关于spring再tomcat启动后,初始化完成后,自动执行一次某个类,怎么做的主要内容,如果未能解决你的问题,请参考以下文章

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

spring boot 测试插件使用及result风格实例1&打包启动.

当spring 容器初始化完成后执行某个方法

当spring 容器初始化完成后执行某个方法

问啥我的web.xml一加Listener,启动tomcat就出错

ssh框架启动Tomcat 不报错也找不到页面 报404错误