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;
    }
}


相关文章
|
3天前
|
小程序 JavaScript Java
基于SpringBoot+Vue+uniapp微信小程序的老孙电子点菜系统的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的老孙电子点菜系统的详细设计和实现
29 1
|
1天前
|
数据采集 监控 安全
java数字工厂MES系统全套源码Java+idea+springboot专业为企业提供智能制造MES解决方案
"MES" 指的是制造执行系统(Manufacturing Execution System)。MES在制造业中扮演着至关重要的角色,它是位于企业资源计划(ERP)系统和车间控制系统之间的系统,用于实时收集、管理、分析和报告与制造过程相关的数据。
9 0
|
2天前
|
SQL Java 调度
SpringBoot使用@Scheduled定时任务录入将要过期任务数据
SpringBoot使用@Scheduled定时任务录入将要过期任务数据
|
2天前
|
JavaScript Java 关系型数据库
基于springboot+vue+Mysql的交流互动系统
简化操作,便于维护和使用。
14 2
|
3天前
|
Java 关系型数据库 MySQL
【毕业设计】基于Springboot的B2B平台医疗病历交互系统
【毕业设计】基于Springboot的B2B平台医疗病历交互系统
12 0
|
3天前
|
搜索推荐 Java 数据库
springboot集成ElasticSearch的具体操作(系统全文检索)
springboot集成ElasticSearch的具体操作(系统全文检索)
|
3天前
|
前端开发 Java 关系型数据库
Java医院绩效考核系统源码B/S架构+springboot三级公立医院绩效考核系统源码 医院综合绩效核算系统源码
作为医院用综合绩效核算系统,系统需要和his系统进行对接,按照设定周期,从his系统获取医院科室和医生、护士、其他人员工作量,对没有录入信息化系统的工作量,绩效考核系统设有手工录入功能(可以批量导入),对获取的数据系统按照设定的公式进行汇算,且设置审核机制,可以退回修正,系统功能强大,完全模拟医院实际绩效核算过程,且每步核算都可以进行调整和参数设置,能适应医院多种绩效核算方式。
31 2
|
3天前
|
运维 监控 Java
springboot基层区域HIS系统源码
医疗(医院)机构正式使用云HIS系统之前,要先进行院内基础数据的配置,主要在数据管理模块中进行,由系统管理员来操作。
14 0
|
3天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
105 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
3天前
|
监控 Java API
Spring Boot与异步任务:整合与应用场景
【4月更文挑战第29天】异步任务在现代应用程序开发中扮演着重要的角色,它们可以提高应用程序的性能和响应速度,尤其适用于处理长时间运行的任务或需要等待外部资源的场景。Spring Boot提供了强大的支持来简化异步任务的实现。
26 0