核心技术: springboot 启动类加载时方法执行的几种实现方式, bean声明周期, 启动执行顺序

news2025/2/26 6:01:05

目录

1. 业务场景

-> 1.1 初始化操作

-> 1.2 业务操作 

-> 1.3优势

2.  实现方式(多种方式,不同思想)

-> 2.1 定时调度任务(常用四种方式 task )

--> 2.1.1 Timer(单线程)

--> 2.1.2 scheduledExecutorService(多线程并发执行,线程池)  

--> 2.1.3 Spring Task (spring自带的Task任务调度)

--> 2.1.4 Quartz 定时任务调度框架 

-> 2.2 CommandLineRunner代码实现>>>>> 

-> 2.3 ApplicationRunner代码实现>>>>>> 

-> 2.4 InitializingBean: bean初始化之后

--> 2.4.1 执行优先级顺序: 

-> 2.4.2 spring的Bean执行介绍以及操作方式

 ---->2.4.2.1: 测试代码一: 

  ---->2.4.2.2: 测试代码二: 

  ---->2.4.2.3: 测试代码三: (测试结果)

 --> 2.4.2 代码实现>>>>>>>>>>>>

-> 2.5 static静态代码块

--> 2.5.1 代码实现>>>>>>>

 --> 2.5.2 测试结果

 -> 2.6 @PostConstruct注解

--> 2.6.1 优先级在2.4.1 里 图片如下: 

--> 2.6.2 常用使用场景代码实现>>>>>>>>>>

3. 文章总结:


1. 业务场景

-> 1.1 初始化操作

想通过查询测试数据库链接以及第一次创建池链接, 读取配置文件等情况

-> 1.2 业务操作 

同步数据, 同步缓存信息, 检测部分功能是否正常运行等

-> 1.3优势

避免了人员操作, 仅启动类加载启动时执行一次即可

2.  实现方式(多种方式,不同思想)

-> 2.1 定时调度任务(常用四种方式 task )

定时调度任务详细介绍: -> 暂无

--> 2.1.1 Timer(单线程)

        包:  java.util.Timer (基本没用)

--> 2.1.2 scheduledExecutorService(多线程并发执行,线程池)  

        包: package java.util.concurrent;

--> 2.1.3 Spring Task (spring自带的Task任务调度)

        注解: @Scheduled(corn="表达式")  void方法上即可

                 @EnableScheduling 启动类添加

        ps: 建议异步执行 不然默认是同步执行(一个线程)

--> 2.1.4 Quartz 定时任务调度框架 

添加依赖: springboot版本

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

    核心: 类继承 QuartzJobBean, 详情请看下文

-> 2.2 CommandLineRunner代码实现>>>>> 

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 类加载时自动执行
 * @author pzy
 * @version 0.1.0
 */
@Order(1) //执行优先级顺序
@Slf4j
@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Value("${spring.auto.user.isAutoCheck:false}")
    private Boolean isAutoCheck;


    @Autowired
    private Controller controller; //直接执行即可 注入bean后使用方法


    @Override
    public void run(String... args) throws Exception {

        if(isAutoCheck){
            log.info("===> MyCommandLineRunner 执行成功 <===")
        }

    }
}

-> 2.3 ApplicationRunner代码实现>>>>>> 

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 类加载时自动执行 方法二
 * @author pzy
 * @version 0.1.0
 */
@Slf4j
@Component //想使用打开即可
@Order(2)   //如果多个自定义的 ApplicationRunner  ,用来标明执行的顺序
public class ApplicationRunnerStartService implements ApplicationRunner {


	@Override
	public void run(ApplicationArguments args) throws Exception {
		log.info("==> 测试初始化 <===");
	}
 
}

-> 2.4 InitializingBean: bean初始化之后

--> 2.4.1 执行优先级顺序: 

静态代码块> 构造代码块> Constructor > @PostConstruct > InitializingBean > init-method

-> 2.4.2 spring的Bean执行介绍以及操作方式

Spring 的 Bean 是有生命周期的, Bean在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下三种:

1. 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法

2. 通过 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法

3. 方法加@PostConstruct 或@PreDestroy注解 表示是在初始化之后还是销毁之前调用

 ---->2.4.2.1: 测试代码一: 

public class OrderCtrlTest {

    static {
        System.out.println("我是一个静态代码块");
    }

    {
        System.out.println("我是一个构造代码块");
    }

    public OrderCtrlTest() {
        System.out.println("我是构造函数");
    }


    public static void main(String[] args) {
        OrderCtrlTest orderCtrlTest = new OrderCtrlTest();

        //执行结果:
        //我是一个静态代码块
        //我是一个构造代码块
        //我是构造函数
    }

}

  ---->2.4.2.2: 测试代码二: 

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;


/**
 * 类加载时自动执行 方法三
 * @author pzy
 * @version 0.1.0
 */
@Slf4j
@Component
public class AutoInitializingRunner implements InitializingBean {

    public AutoInitializingRunner() {
        log.info("==> 1: AutoInitializingRunner的构造方法");
    }

    @Bean
    public void initMethod() {
        log.info("==> 3: initMethod 方法");
    }

    @Override
    public void afterPropertiesSet() {
        log.info("==> 2: 执行InitializingBean的唯一重写方法");
    }
}

  ---->2.4.2.3: 测试代码三: (测试结果)

 --> 2.4.2 代码实现>>>>>>>>>>>>

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;


/**
 * 类加载时自动执行 方法三
 * @author pzy
 * @version 0.1.0
 */
@Slf4j
@Component
public class AutoInitializingRunner implements InitializingBean {

 
    @Override
    public void afterPropertiesSet() {
        log.info("==> 1: 执行InitializingBean的唯一重写方法");
    }
}

-> 2.5 static静态代码块

--> 2.5.1 代码实现>>>>>>>

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableScheduling
//@EnableRabbit
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "*")
@EnableTransactionManagement
@ComponentScan(basePackages={"*"})
@MapperScan("*")
@Slf4j
@SpringBootApplication
public class AaaApplication {

	static{
		System.out.println("静态代码块执行部分业务可以!");
		log.info("===> 静态代码块执行部分业务可以!");
	}
	
	public static void main(String[] args) {
		SpringApplication.run(AaaApplication.class, args);
	}
}

 --> 2.5.2 测试结果

 -> 2.6 @PostConstruct注解

--> 2.6.1 优先级在2.4.1 里 图片如下: 

--> 2.6.2 常用使用场景代码实现>>>>>>>>>>

    @Value("${spring.redis.host}")
    public String ip;

    @Value("${spring.redis.password}")
    public String redisPassword;

    public static String IP;
    public static String REDIS_PASSWORD;

    @PostConstruct
    public void init() {
        IP = ip;
        REDIS_PASSWORD = redisPassword;
    }

3. 文章总结:

实现一个功能有不同的解决方式, 只有不断的尝试, 探索, 寻找到与当前业务更加贴合的技术, 技术是为业务服务的, 制作不易

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SmoothNLP新词发现算法的改进实现

SmoothNLP新词发现算法的改进实现 背景介绍 新词发现也叫未登录词提取&#xff0c;依据 《统计自然语言处理》(宗成庆)&#xff0c;中文分词有98%的错误来自"未登录词"。即便早就火遍大江南北的Bert也不能解决"未登录词"的Encoding问题&#xff0c;便索性…

棋牌类游戏测试用例怎么写?我敢打赌你绝对不知道

目录 一&#xff0e;登陆 二&#xff0e;大厅 三&#xff0e;小游戏 四&#xff0e;银行功能 五&#xff0e;其他按钮 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 一&#xff0e;登陆 1&#xff0e…

Redis高可用集群方案

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 @[TOC](文章目录)主从复制哨兵模式(sentinel)Cluster集群在生产过程中,Redis不一定会单独部署。因为一旦redis服务因为某些原因导致无法提供数,那么redis就不可用了。那么实现redis高可用的方式就…

Orin装机

安装目录orin刷机谷歌输入法ROS遇到的问题&#xff1a;1、sudo rosdep init2、rosdep updatelibrealsenserealsense_ros安装librealsense安装realsense_ros总的来说就是&#xff0c;注意librealsense和realsense-ros的版本&#xff0c;对于librealsense&#xff0c;采用源码安装…

企业级分布式应用服务 EDAS

什么是企业级分布式应用服务EDAS企业级分布式应用服务EDAS&#xff08;Enterprise Distributed Application Service&#xff09;是一个应用托管和微服务管理的云原生PaaS平台&#xff0c;提供应用开发、部署、监控、运维等全栈式解决方案&#xff0c;同时支持Spring Cloud和Ap…

gcc/g++、动静态库、make/makefile

目录 gcc/g gcc和g的对比 "一段代码的使命" ●预处理 ●编译 ●汇编 ●链接 ●动/静态链接 make/makefile gcc/g gcc和g的对比 对于c文件而言&#xff0c;使用gcc或者g并没有什么区别。而对于cpp文件&#xff0c;在预处理、编译、汇编这三部分&#xff0c;…

《精通Spring4.x 企业应用开发实战》第1章 Spring概述

目录标题前言一、Spring带给我们什么二、Spring体系结构三、Spring4.0新特性核心容器的增强泛型依赖注入Map依赖注入Lazy延迟依赖注入List注入Conditional 注解CGLIB 代理类增强其他四、Spring 子项目总结前言 汇总&#xff1a;《精通Spring4.x 企业应用开发实战》 一、Spring带…

L2-010 排座位

布置宴席最微妙的事情&#xff0c;就是给前来参宴的各位宾客安排座位。无论如何&#xff0c;总不能把两个死对头排到同一张宴会桌旁&#xff01;这个艰巨任务现在就交给你&#xff0c;对任何一对客人&#xff0c;请编写程序告诉主人他们是否能被安排同席。 输入格式&#xff1…

【LeetCode】剑指 Offer 10- II. 青蛙跳台阶问题 p77 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/ 1. 题目介绍&#xff08;10- II. 青蛙跳台阶问题&#xff09; 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取…

采购评标管理过程是怎样的?有哪些评标标准?

采购活动的评标是检查和比较投标的有组织的过程&#xff0c;以选择最佳报价&#xff0c;努力获得实现企业目标所需的货物、工程和服务。 评标是由一个被称为评标小组的机构负责。这个小组如何称呼&#xff0c;取决于企业的情况。同义词有报价审查小组、投标审查委员会或投标审…

在ONLYOFFICE中借助ChatGPT一键创建招聘启事的内容

大家好&#xff0c;相信和多人都在生活中或工作中看到过招聘启示&#xff0c;或多或少都会有些了解。今天教大家在ONLYOFFICE中怎样通过chetGPT创建一份满意的招聘启示&#xff0c;下面是我用chatgpt制作的一份招聘信息&#xff0c;请大家看一下。 ONLYOFFICE ONLYOFFICE文档是…

从0到1实现单机记账APP原理与细节uniApp内含源码 (一)

单机记账APP演示及源码 具体演示如下面视频所示。免费下载地址&#xff1a;点击进入 预览APP&#xff08;内含开屏广告&#xff09;下载地址&#xff1a;http://8.142.10.182:8888/down/aWHWeGaEQE2W.apk 服务器买的便宜&#xff0c;带宽很小所以下载速度慢&#xff0c;主要还…

mathtype7.0最新版安装下载及使用教程

MathType是一款专业的数学公式编辑器&#xff0c;理科生专用的必备工具&#xff0c;可应用于教育教学、科研机构、工程学、论文写作、期刊排版、编辑理科试卷等领域。2014年11月&#xff0c;Design Science将MathType升级到MathType 6.9版本。在苏州苏杰思网络有限公司与Design…

APP任务模块功能借助php-resque实现业务解耦

先上设计图 说明&#xff1a;任务模块分一次性任务和每日任务&#xff0c;可能还包括男女用户任务区分 处理步骤&#xff1a; 一、同步任务数据库 1.1、任务列表数据库 1.2、完成任务数据库 二、搭建即时消息队列 一、composer require resque/php-resque二、因为服务器red…

数据结构:栈和队列(Leetcode20. 有效的括号+225. 用队列实现栈+232. 用栈实现队列)

目录 一.数据结构--栈 1.栈的基本介绍 2.栈的实现 二.数据结构--队列 1.队列的基本介绍 2.队列的实现 三.栈的运用(Leetcode20. 有效的括号225) 1.问题描述 2.问题分析 题解代码&#xff1a; 四.用两个队列实现栈(225. 用队列实现栈 - 力扣&#xff08;Leetcode&a…

Talk | 清华大学交叉信息研究院助理教授杜韬:利用计算方法探究流固耦合

本期为TechBeat人工智能社区第474期线上Talk&#xff01; 北京时间2月15日(周三)20:00&#xff0c;清华大学交叉信息研究院助理教授——杜韬的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “利用计算方法探究流固耦合”&#xff0c;届时将介绍流固…

Windows10使用-处理IE自动跳转至Edge

文章目录 前言一、调整Edge二、调整Internet选项三、搜索栏的恢复总结前言 微软官方宣布,自2023年2月14日永久停止支持Internet Explorer 11浏览器。后期点击IE 图标将会自动跳转到Edge界面。对于一些网站,可能需要使用IE模式才能正常使用,这时候就需要做相应的调整,才能够…

做外贸怎么找客户

现在国内贸易内卷非常严重&#xff0c;很多商家都转向海外市场了&#xff0c;总结而言&#xff0c;目前所有做外贸的人&#xff0c;核心的点就是要找到重点意向客户&#xff0c;今天就和大家分享一下目前市面上外贸找客户的几种方法。主动出击式开发外贸客户1、参加展会找外贸客…

使用拦截器实现登录状态检测(以及在注册拦截器类时要使用ioc中的拦截器类)

拦截器 preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) 方法在请求处理之前被调用。该方法在 Interceptor 类中最先执行&#xff0c;用来进行一些前置初始化操作或是对当前请求做预处理&#xff0c;也可以进行一些判断来决定请求是否…

C++类和对象-继承多态

继承 继承是面向对象三大特性之一 定义类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性&#xff0c;就可以考虑使用继承的技术&#xff0c;减少代码的重复 继承的基本语法 语法&#xff1a;class 子类 : 继承方式 父类 子类也被成为派生类父类…