SpringBoot系统启动任务(三十二)的方式(上)

简介: SpringBoot系统启动任务(三十二)的方式(上)

一. 系统启动时执行定时任务

一.一 服务启动后执行定时任务

在系统启动时,我们常常需要初始化一些数据,如构造出必要的数据,将数据库中的某些数据提前写入到缓存里面,获取当前服务器的相关信息等。

@SpringBootApplication
public class InitApplication {
    public static void main(String[] args) {
        SpringApplication.run(InitApplication.class,args);
        System.out.println(">>>>>>>项目启动成功");
        //执行初始化数据.
        initData();
    }
    public static void initData(){
        System.out.println("静态方法初始化数据");
    }
}


这样的操作, initData() 并不是系统启动时执行的定时任务,而是系统启动后执行的.

image.png



这样写,当不牵扯到组件 @Component 相关的注解方法时,也就是说只有简单的方法处理时,虽然可以进行初始化数据,但不规范,一般不采用这种方式处理.


本章节代码层次结构如下:


image.png


定义一个接口和一个实现


UserService 接口

public interface UserService {
    public void set();
    public void get();
}


UserServiceImpl 实现

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void set() {
        System.out.println("UserService--->set值");
    }
    @Override
    public void get() {
        System.out.println("UserService--->取出值");
    }
}


一.二 Listener 监听器执行定时任务

在 JSP /Servlet 时,我们常常使用 Listener 监听器来初始化数据.


SpringBoot 也支持这种形式.

一.二.一 事件监听器 InitListener

在 listener 包下创建事件监听器

package top.yueshushu.init.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
 * @ClassName:InitListener
 * @Description 监听器
 * @Author zk_yjl
 * @Date 2021/11/30 9:00
 * @Version 1.0
 * @Since 1.0
 **/
public class InitListener implements ServletContextListener {
    /**
      容器启动时
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //初始化必要的数据. 常于构建缓存,初始化数据.
        System.out.println(">>>>Listener,容器启动,初始化必要的数据");
    }
    /**
     容器突然销毁时
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //容器关闭了,进行数据备份的处理.
        System.out.println(">>>>Listener,容器销毁,将重要数据备份");
    }
}


一.二.二 启动添加 Listener

@SpringBootApplication
public class InitApplication {
    public static void main(String[] args) {
        SpringApplication.run(InitApplication.class,args);
        System.out.println(">>>>>>>项目启动成功");
        //执行初始化数据.
       // initData();
    }
   /* public static void initData(){
        System.out.println("静态方法初始化数据");
    }
*/
    /**
     * 添加Listener
     * @date 2021/11/30 9:03
     * @author zk_yjl
     * @return
     */
    @Bean
    public ServletListenerRegistrationBean<InitListener> initListenerServletListenerRegistrationBean(){
        ServletListenerRegistrationBean<InitListener> registrationBean=new ServletListenerRegistrationBean<>(
                new InitListener()
        );
        return registrationBean;
    }
}



在项目启动之前执行了,初始化 ExecutorService 之前.


二. SpringBoot 系统启动任务

通常使用 CommandLineRunner , ApplicationRunner , 和 @PostConstruct三种方式进行处理


关于参数的使用,可以参考江南一点雨大神的这篇文章.


二.一 CommandLineRunner 方式

如启动时,获取机器码


二.一.一 获取机器码的工具类 HardwareUtil

package top.yueshushu.init.util;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Scanner;
@Log4j2
public class HardwareUtil {
    private static final String[] getCpuIdWindows = {"wmic", "cpu", "get", "ProcessorId"};
    private static String cpuId;
    public static String getCpuId() {
        try{
            String osName = getOsName();
            String cpuId = null;
            if (osName.toLowerCase().contains("linux")) {
                cpuId = getSerialNumber("dmidecode -t processor | grep 'ID'", "ID", ":");
            } else if (osName.toLowerCase().contains("windows")) {
                cpuId = getWindowsCpuId();
            }
            return !StringUtils.hasText(cpuId)?"1020304050607080":cpuId;
        }catch (Exception e){
            log.error("生成CpuId错误",e);
            return "1020304050607080";
        }
    }
    private static String getWindowsCpuId() {
        try {
            Process process = Runtime.getRuntime().exec(getCpuIdWindows);
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String property = sc.next();
            String serial = sc.next();
            log.info(property + ": " + serial);
            return serial;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            log.error("发生异常", e);
        }
        return null;
    }
    public static String getMac() {
        NetworkInterface networkInterface = getRealNetworkInterface();
        try {
            if (networkInterface == null) {
                return null;
            }
            byte[] mac = networkInterface.getHardwareAddress();
            return buildMac(mac);
        } catch (SocketException e) {
            log.error("发生异常{}", e);
        }
        return null;
    }
    public static String getServerId() {
        return buildServerId(getIpAddress());
    }
    private static String getIpAddress() {
        NetworkInterface networkInterface = HardwareUtil.getRealNetworkInterface();
        return networkInterface.getInterfaceAddresses().get(0).getAddress().getHostAddress();
    }
    private static NetworkInterface getRealNetworkInterface() {
        try {
            //枚举本机所有的网络接口
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                // 去除回环接口,子接口,未运行和接口
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    continue;
                }
                return netInterface;
            }
        } catch (SocketException e) {
            System.err.println("Error when getting host ip address" + e.getMessage());
        }
        return null;
    }
    private static String buildServerId(String address) {
        List<String> ips = Arrays.asList(address.split("\\."));
        return ips.stream().mapToInt(Integer::parseInt).boxed().map(Object::toString).reduce("", String::concat);
    }
    private static String buildMac(byte[] mac) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        return sb.toString().toUpperCase();
    }
    private static String getOsName() {
        return System.getProperty("os.name");
    }
    private static String getSerialNumber(String cmd, String record, String symbol) {
        String execResult = executeLinuxCmd(cmd);
        String[] infos = execResult.split("\n");
        for (String info : infos) {
            info = info.trim();
            if (info.contains(record)) {
                info.replace(" ", "");
                String[] sn = info.split(symbol);
                return sn[1];
            }
        }
        return null;
    }
    private static String executeLinuxCmd(String cmd) {
        try {
            log.debug("got cmd job : " + cmd);
            Runtime run = Runtime.getRuntime();
            Process process;
            process = run.exec(cmd);
            InputStream in = process.getInputStream();
//            BufferedReader bs = new BufferedReader(new InputStreamReader(in));
            StringBuffer out = new StringBuffer();
            byte[] b = new byte[8192];
            for (int n; (n = in.read(b)) != -1; ) {
                out.append(new String(b, 0, n));
            }
            in.close();
            process.destroy();
            return out.toString();
        } catch (Exception e) {
            log.error("发生异常", e);
        }
        return null;
    }
}


相关文章
|
1月前
|
JavaScript Java 关系型数据库
基于springboot的项目管理系统
本文探讨项目管理系统在现代企业中的应用与实现,分析其研究背景、意义及现状,阐述基于SSM、Java、MySQL和Vue等技术构建系统的关键方法,展现其在提升管理效率、协同水平与风险管控方面的价值。
|
1月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
1月前
|
JavaScript Java 关系型数据库
基于springboot的古树名木保护管理系统
本研究针对古树保护面临的严峻挑战,构建基于Java、Vue、MySQL与Spring Boot技术的信息化管理系统,实现古树资源的动态监测、数据管理与科学保护,推动生态、文化与经济可持续发展。
|
30天前
|
监控 安全 JavaScript
2025基于springboot的校车预定全流程管理系统
针对传统校车管理效率低、信息不透明等问题,本研究设计并实现了一套校车预定全流程管理系统。系统采用Spring Boot、Java、Vue和MySQL等技术,实现校车信息管理、在线预定、实时监控等功能,提升学校管理效率,保障学生出行安全,推动教育信息化发展。
|
2月前
|
存储 JavaScript Java
基于springboot的大学公文收发管理系统
本文介绍公文收发系统的研究背景与意义,分析其在数字化阅读趋势下的必要性。系统采用Vue、Java、Spring Boot与MySQL技术,实现高效、便捷的公文管理与在线阅读,提升用户体验与信息处理效率。
|
1月前
|
人工智能 Java 关系型数据库
基于springboot的画品交流系统
本项目构建基于Java+Vue+SpringBoot+MySQL的画品交流系统,旨在解决传统艺术交易信息不透明、流通受限等问题,融合区块链与AI技术,实现画品展示、交易、鉴赏与社交一体化,推动艺术数字化转型与文化传播。
|
1月前
|
JavaScript Java 关系型数据库
基于springboot的高校运动会系统
本系统基于Spring Boot、Vue与MySQL,实现高校运动会报名、赛程安排及成绩管理的全流程信息化,提升组织效率,杜绝信息错漏与冒名顶替,推动体育赛事智能化发展。
|
27天前
|
JavaScript 安全 Java
基于springboot的大学生兼职系统
本课题针对大学生兼职信息不对称、权益难保障等问题,研究基于Spring Boot、Vue、MySQL等技术的兼职系统,旨在构建安全、高效、功能完善的平台,提升大学生就业竞争力与兼职质量。
|
1月前
|
JavaScript Java 关系型数据库
基于springboot的美食城服务管理系统
本系统基于Spring Boot、Java、Vue和MySQL技术,构建集消费者服务、商家管理与后台监管于一体的美食城综合管理平台,提升运营效率与用户体验。