Spring加载后初始化的9种方式

news2024/11/20 18:30:32

本文来聊一下在spring中,当spring 容器启动后,我们有几种初始化操作的方式。

目录

Spring加载后初始化的几种方式

@Component和@Service加构造方法

ContextRefreshedEvent事件

代码如下:

输出结果:

PostConstruct 注解

代码如下:

输出结果:

InitializingBean

代码如下:

输出结果:

init-method方法

代码如下:

输出结果:

实现 SmartInitializingSingleton 接口

代码如下:

输出结果:

重写 onRefresh()方法

CommandLineRunner(仅限Spring Boot)

代码如下:

输出结果:

SpringApplicationRunListener(仅限Spring boot)

代码如下:

输出结果:

总结:


Spring加载后初始化的几种方式

  1. @component和@service 加构造方法

  2. ContextRefreshedEvent事件

  3. PostConstruct 注解

  4. InitializingBean

  5. init-method方法

  6. 实现 SmartInitializingSingleton 接口

  7. 重写 onRefresh()方法

  8. CommandLineRunner(仅限Spring Boot)

  9. SpringApplicationRunListener(仅限Spring boot)

在spring 容器中有一个 Persion对象名字叫张三,需要在spring容器启动后调用它的run方法。代码如下


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
@Configuration
public class PersonConfig {
​
    @Bean
    public Person person(){
        Person person = new Person();
        person.setName("张三");
        person.setAge(18);
        return person;
    }
}
​

@Component和@Service加构造方法

import org.springframework.stereotype.Component;
​
@Component
//@Service
public class PersonConfig {
​
    private Person person;
​
    public PersonConfig() {
        person = new Person();
        person.setName("张三");
        person.setAge(18);
    }
}

ContextRefreshedEvent事件

ContextRefreshedEvent:是Spring容器初始化完成后调用的事件。 ContextRefreshedEvent的父类是ApplicationContextEvent,是一个事件。所以我们通过ApplicationListener来实现。

代码如下:

import com.example.springbootdemo.bean.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
​
@Component
public class PersonAfterListener implements ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    private Person person;
​
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        person.run("ContextRefreshedEvent");
    }
}
​

输出结果:

输出结果

PostConstruct 注解

PostConstruct注解修饰的方式,是在spring容器启动时运行的。优先级大于ContextRefreshedEvent事件。

代码如下:

import com.example.springbootdemo.bean.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import javax.annotation.PostConstruct;
​
@Component
public class PersonAfterPostConstruct {
    @Autowired
    private Person person;
​
    @PostConstruct
    public void postConstruct(){
        person.run("PostConstruct");
    }
}
​

输出结果:

输出结果 由此可见,PostConstruct优先级大于ContextRefreshedEvent事件。

InitializingBean

InitializingBean是spring容器在启动并初始化好内部示例后调用的,用来最终为总体bean添加最后属性和操作。 官方原话:This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.

代码如下:

import com.example.springbootdemo.bean.Person;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
@Component
public class PersonAfterInitializingBean implements InitializingBean {
    @Autowired
    private Person person;
​
    @Override
    public void afterPropertiesSet() throws Exception {
        person.run("InitializingBean");
    }
}
​

输出结果:

输出结果

init-method方法

这种方法有一定的局限性,并且可能会覆盖曾经的init操作,需要慎用。

Bean在加载到Spring容器中时需要先将Bean的定义信息抽象为BeanDefinition,其中有一个属性init-method代表将来Bean初始化时要调用的方法。

我们通过BeanFactoryPostProcessor来注入init-method方法,并且该方法必须是没有参数的

代码如下:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
​
@Component
public class PersonAfterInit implements BeanFactoryPostProcessor {
​
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition person = beanFactory.getBeanDefinition("person");
        person.setInitMethodName("run");
    }
}
​

输出结果:

输出结果

实现 SmartInitializingSingleton 接口

SmartInitializingSingleton是Bean容器在初始化所有非懒加载的单例Bean后调用的方法。

代码如下:

import com.example.springbootdemo.bean.Person;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
@Component
public class PersonAfterSmartInitializingSingleton implements SmartInitializingSingleton {
    @Autowired
    private Person person;
​
    @Override
    public void afterSingletonsInstantiated() {
        person.run("SmartInitializingSingleton");
    }
}
​

输出结果:

输出结果

重写 onRefresh()方法

这个我实在是不会,但我不藏着掖着,告诉你也能实现。

CommandLineRunner(仅限Spring Boot)

CommandLineRunner 是一个Spring boot 接口,在应用初始化后执行,且仅会执行一次。可以用来打印项目中配置文件的参数,方便排查问题。

代码如下:

import com.example.springbootdemo.bean.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
​
@Component
public class PersonAfterCommandLineRunner implements CommandLineRunner {
    @Autowired
    private Person person;
​
    @Override
    public void run(String... args) throws Exception {
        person.run("CommandLineRunner");
    }
}
​

输出结果:

输出结果

SpringApplicationRunListener(仅限Spring boot)

SpringBoot的生命周期事件监听方法,需要搭配resource/META-INF/spring.factories 文件使用。

代码如下:

JAVA代码:

import com.example.springbootdemo.bean.Person;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
​
import java.time.Duration;
​
​
public class PersonAfterSpringApplicationRunListener implements SpringApplicationRunListener {
    private final SpringApplication application;
    private final String[] args;
​
    public PersonAfterSpringApplicationRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.args = args;
    }
​
    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        /*
         * Person has not been registered
         */
//        Person person = bootstrapContext.get(Person.class);
//        person.run("SpringApplicationRunListener:starting");
    }
​
    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        /*
         * Person has not been registered
         */
//        Person person = bootstrapContext.get(Person.class);
//        person.run("SpringApplicationRunListener:environmentPrepared");
    }
​
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        /*
         * Person has not been registered
         */
//        Person person = context.getBean(Person.class);
//        person.run("SpringApplicationRunListener:contextPrepared");
    }
​
    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        /*
         * Person has not been registered
         */
//        Person person = context.getBean(Person.class);
//        person.run("SpringApplicationRunListener:contextLoaded");
    }
​
    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        Person person = context.getBean(Person.class);
        person.run("SpringApplicationRunListener:started");
    }
​
    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        Person person = context.getBean(Person.class);
        person.run("SpringApplicationRunListener:ready");
    }
​
    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        Person person = context.getBean(Person.class);
        person.run("SpringApplicationRunListener:failed");
    }
}
​

spring.factories

    org.springframework.boot.SpringApplicationRunListener=com.example.springbootdemo.impl.PersonAfterSpringApplicationRunListener

输出结果:

输出结果

总结:

执行优先级:init-Method >> InitializingBean >> PostConstruct >> SmartInitializingSingleton >> ContextRefreshedEvent >> SpringApplicationRunListener:started >> CommandLineRunner >> SpringApplicationRunListener:ready

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

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

相关文章

基于骨骼关键点的动作识别(OpenMMlab学习笔记,附PYSKL相关代码演示)

一、骨骼动作识别 骨骼动作识别是视频理解领域的一项任务 1.1 视频数据的多种模态 RGB&#xff1a;使用最广&#xff0c;包含信息最多&#xff0c;从RGB可以得到Flow、Skeleton。但是处理需要较大的计算量 Flow&#xff1a;光流&#xff0c;主要包含运动信息&#xff0c;处理…

面向对象分析与设计 UML2.0 学习笔记

一、认识UML UML-Unified Modeling Language 统一建模语言&#xff0c;又称标准建模语言。是用来对软件密集系统进行可视化建模的一种语言。UML的定义包括UML语义和UML表示法两个元素。 UML是在开发阶段&#xff0c;说明、可视化、构建和书写一个面向对象软件密集系统的制品的…

Hyper-V虚拟机在wifi环境下的外网连接配置

目录 什么是虚拟交换机管理器了解虚拟交换机中的三个概念通过无线网卡创建虚拟交换机遇到的问题wifi环境下虚拟机外网连接方法 前面我们已经安装好了Hyper-V虚拟机和liunx操作系统&#xff0c;但是我们没有给虚拟机配置网络&#xff0c;本来我以为是一件很简单的事情&#xff0…

【Spring Boot学习】怎么配置文件,配置文件有什么用

前言&#xff1a; &#x1f49e;&#x1f49e;今天我们依然是学习Spring Boot&#xff0c;这里我们会更加了解Spring Boot的知识&#xff0c;知道Spring Boot的配置文件是什么样子的。有什么用&#xff1f;怎么使用Spring Boot的配置文件。 &#x1f49e;&#x1f49e;路漫漫&a…

Apache James 同时开启25、587、465端口

前提&#xff1a; 可以参考如下两篇文章在window或者linux上&#xff0c;先部署好Apache James Apache James邮件服务器搭建&#xff08;linux&#xff09;_Steven-Russell的博客-CSDN博客 Apache James邮件服务器搭建&#xff08;windows&#xff09;_Steven-Russell的博客…

Qt6.2教程——6.QT常用控件QLineEdit

一&#xff0c;QLineEdit简介 QLineEdit是Qt库中的一个控件&#xff0c;它提供了一个单行的文本输入框。用户可以在这个输入框中输入和编辑文本。它可以设置占位符文本&#xff08;Placeholder Text&#xff09;&#xff0c;当QLineEdit为空的时候显示这个占位符文本。它还可以…

JDK8新特性之方法引用【 ::】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于方法引用的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.是什么 二.为什么要用 三.什么时候…

chrome录制保存网络请求

有时候&#xff0c;需要与同事共同查看网络请求&#xff0c;但是现场往往环境限制&#xff0c;导致无法访问环境。在这里推荐一种利用chrome保存网络请求的方法。 准备&#xff1a; 1. chrome浏览器&#xff08;最好版本号是62以上&#xff09; chrome浏览器越新越好(最新稳定…

rsarsa

数学很酷&#xff01;使用RSA算法对秘密消息进行解码&#xff0c;c&#xff0c;p&#xff0c;q&#xff0c;e是RSA算法的参数。 RSA算法还不太了解&#xff0c;经过这段时间的学习&#xff0c;得知 q和p是最开始选择的两个质数&#xff0c;主要是为了计算出钥匙n e是在1到φ(n)…

服务器编程:数据库连接池

引言&#xff1a; 数据库连接池和线程池的思想一样&#xff0c;是为了避免频繁创建和销毁数据库连接导致的性能开销。如果一个项目频繁的需要访问数据库&#xff0c;那么它就有可能需要频繁的创建/销毁数据库连接&#xff0c;那么我们可以采用数据库连接池的技术&#xff0c;在…

Docker中搭建RabbitMQ集群

Docker中搭建RabbitMQ集群 1、启动三个RabbitMQ容器2、为容器设置节点2.1、设置Erlang Cookie2.2、设置节点12.3、设置节点22.4、设置节点32.5、预览结果 3、配置镜像队列3.1、配置镜像的原因3.2、搭建步骤 1、启动三个RabbitMQ容器 服务器IP端口hostname管理界面地址192.168.…

IoC容器的设计(利用反射、注解和工厂模式实现)

1.实验要求 利用注解、反射和工厂模式设计一个简单的IoC容器该IoC容器包含3个注解和一个IoC容器类&#xff08;AnnotationConfigApplicationContext&#xff09;&#xff0c;其定义如下&#xff1a; 注解&#xff1a; 注解含义Component标注BeanAutowired标注需要被注入的对…

如何写好一份企业直播主题策划?

写一份好的直播主题策划&#xff0c;需要考虑包括目标受众、目的、内容、形式、互动等&#xff0c;下面是写企业直播主题策划的一些关注点&#xff0c;希望能帮到您。 定位您直播的目标受众 明确你的直播主题适合的目标受众是谁&#xff0c;他们的兴趣、需求和期望是什么。了解…

OAuth2,jwt,springsecurity之间的区别和联系

OAuth 2.0、JWT (JSON Web Token) 和 Spring Security 是安全相关的概念和技术&#xff0c;它们有着不同的功能和用途。 OAuth 2.0&#xff08;开放授权&#xff09;&#xff1a; OAuth 2.0 是一种授权框架&#xff0c;用于授权第三方应用程序访问用户资源&#xff0c;而无需共…

【OpenCV DNN】Flask 视频监控目标检测教程 10

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 10 3.10 OpenCV DNNFlask实时监控目标检测1、加载MobileNet SSD模型2、导入分类名称文件3、处理视频帧进行目标检测4、新建一个Flask项目5、Python 程序文件6、视频流的网…

linux系统addr ip以及ifconfig查询不到ip地址解决方法,没有ens33

先看使用情况 网上一堆垃圾博文解决方案都是你抄我我抄你&#xff0c;一点用没有&#xff0c;都说使用 vi /etc/sysconfig/network-scripts/ifcfg-ens33 来更改配置ONBOOT为yes&#xff0c;改个屁&#xff0c;给你们看看我目前的配置&#xff0c;劳资本身就是yes&#xff0c;还…

Elasticsearch 基本使用(二)简单查询 嵌套查询

查询数据 简单查询按id查询单条记录查询所有数据设置排序filter 过滤查询数组内的值查询 嵌套查询查询一个外层字段 内的嵌套字段查询多个字段&#xff0c;其中有嵌套字段 简单查询 按id查询单条记录 GET bank/_doc/1查询所有数据 默认只查询10条记录 GET bank/_search {&q…

Linux任务调度、磁盘分区、挂载

一、任务调度介绍 任务调度是指系统在某个时间执行的特定的命令或程序 任务调度分为两类&#xff1a; 1.系统工作&#xff1a;有些重要的工作必须周而复始的执行&#xff0c;比如病毒扫描 2&#xff0c;个别用户工作&#xff1a;个别用户可能希望执行某些程序&#xff0c;比如…

canvas自定义绘制顺序解决遮挡问题

canvas自定义绘制顺序解决遮挡问题 1. 问题场景2. 解决思路3. 实现代码 1. 问题场景 使用canvas绘制进行要素叠加时&#xff0c;往往会出现不是按照先画的在下面&#xff0c;后画的在最上面这样的顺序进行叠加显示。原因就是由于图片大小不同导致绘制或加载的时间不一样&#…