Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >springBoot学习(四)项目初始化的开始和结束

springBoot学习(四)项目初始化的开始和结束

作者头像
杨小杰
发布于 2019-07-04 08:26:26
发布于 2019-07-04 08:26:26
86100
代码可运行
举报
运行总次数:0
代码可运行

ApplicationContextInitializer接口

用来初始化Spring ConfigurableApplicationContext应用上下文的回调接口,是在ConfigurableApplicationContext.refresh()之前调用。 该接口典型的应用场景是web应用中需要编程方式对应用上下文做初始化。比如,注册属性源(property sources)或者针对上下文的环境信息environment激活相应的profile

代码实现
默认的application.properties文件(默认指定为生产环境)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test.name=default
spring.profiles.active=prd
application-dev.properties文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test.name=dev
application-prd.properties文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test.name=prd
自定义MyApplicationContextInitializer实现ApplicationContextInitializer接口,重写initialize方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring.Initializer;

import com.yxj.spring.SpringBootTestRun;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.Initializer
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 22:39
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 22:39
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    /**
     * 1.springBoot执行ApplicationContextInitializer refresh方法之前会先执行
     * 2.在方法中设置活动配置文件为dev(该结果可以从其他途径去获取,这里给定默认值dev)
     * 3.在启动类最后获取name,查看最终结果
     * @param applicationContext
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        applicationContext.getEnvironment().setActiveProfiles("dev");
        System.out.println("-------初始化---------");
    }
}
springBoot启动类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring;

import com.yxj.spring.Initializer.MyApplicationContextInitializer;
import com.yxj.spring.monitor.MyApplicationListener;
import com.yxj.spring.monitor.MyEvent;
import com.yxj.spring.properties.TestProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

import java.util.List;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/18 20:18
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/18 20:18
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@SpringBootApplication
public class SpringBootTestRun {

    @Value("${test.name}")
    private String testName;

    /**
     * 添加初始化类方式
     * 1.springBootTestRun.addInitializers(new MyApplicationContextInitializer());
     * 2.通过配置项来指定(context.initiallzer.classes=com.yxj.spring.Initializer.MyApplicationContextInitializer)
     * 3.spring.factories机制
     * 应用:
     * 当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入
     * 在日常工作中,我们可能需要实现一些SDK或者Spring Boot Starter给被人使用,这个使用我们就可以使用Factories机制。
     * Factories机制可以让SDK或者Starter的使用只需要很少或者不需要进行配置,只需要在服务中引入我们的jar包。
     * 详细使用参考:http://blog.51cto.com/13836814/2134630
     *
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication springBootTestRun = new SpringApplication(SpringBootTestRun.class);
        //springBootTestRun.addInitializers(new MyApplicationContextInitializer());
        ConfigurableApplicationContext run = springBootTestRun.run(args);
        SpringBootTestRun bean = run.getBean(SpringBootTestRun.class);
        System.out.println("------------分割线------------");
        System.out.println(bean.testName);
        run.close();
    }
}
测试结果
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-------初始化---------


------------分割线------------
dev
CommandLineRunner和ApplicationRunner接口

CommandLineRunner、ApplicationRunner 接口是在容器启动成功后的最后一步回调。如果希望在项目启动完成之前,初始化一些操作,可以使用这两个接口。

实现
  • 实现CommandLineRunner或者ApplicationRunner接口
  • 实现run方法
  • 通过@Component或者其他方式添加到spring容器管理中
  • 可以实现多个,通过@Order(value = XXX)的方式,可以实现排序
CommandLineRunner接口

第一个CommandLineRunner

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring.runner;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:10
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:10
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 4)
public class MyCommandLineRunner1 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("order value is 4   。MyCommandLineRunner1 run.  get args : "+Arrays.asList(args));
    }
}

第二个CommandLineRunner

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring.runner;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:10
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:10
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 1)
public class MyCommandLineRunner2 implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("order value is 1   。MyCommandLineRunner2 run.  get args : "+Arrays.asList(args));
    }
}

第一个ApplicationRunner

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring.runner;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:27
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:27
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 3)
public class MyApplicationRunner1 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        for(String argsString :args.getOptionNames()){
            System.out.println("order value is 3   。MyApplicationRunner1 is ApplicationArguments key : ("+argsString + ")   ApplicationArguments value : ("+args.getOptionValues(argsString)+")");
        }
    }
}

第二个ApplicationRunner

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring.runner;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring.runner
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/25 23:27
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/25 23:27
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@Component
@Order(value = 2)
public class MyApplicationRunner2 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        for(String argsString :args.getOptionNames()){
            System.out.println("order value is 2   。MyApplicationRunner2 is ApplicationArguments key : ("+argsString + ")   ApplicationArguments value : ("+args.getOptionValues(argsString)+")");
        }
    }
}

springBoot测试启动类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yxj.spring;

import com.yxj.spring.Initializer.MyApplicationContextInitializer;
import com.yxj.spring.monitor.MyApplicationListener;
import com.yxj.spring.monitor.MyEvent;
import com.yxj.spring.properties.TestProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

import java.util.List;

/**
 * @ProjectName: springBootDemo
 * @Package: com.yxj.spring
 * @Description:
 * @Author: 阿杰
 * @CreateDate: 2019/1/18 20:18
 * @UpdateUser: 暂无
 * @UpdateDate: 2019/1/18 20:18
 * @UpdateRemark: The modified content
 * @Version: 1.0
 */
@SpringBootApplication
public class SpringBootTestRun {

    @Value("${test.name}")
    private String testName;

    public static void main(String[] args) {
        SpringApplication springBootTestRun = new SpringApplication(SpringBootTestRun.class);
        ConfigurableApplicationContext run = springBootTestRun.run("测试1","测试2","--key1=测试3","--key2=测试4");
        run.close();
    }
}

测试结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
order value is 1   。MyCommandLineRunner2 run.  get args : [测试1, 测试2, --key1=测试3, --key2=测试4]
order value is 2   。MyApplicationRunner2 is ApplicationArguments key : (key1)   ApplicationArguments value : ([测试3])
order value is 2   。MyApplicationRunner2 is ApplicationArguments key : (key2)   ApplicationArguments value : ([测试4])
order value is 3   。MyApplicationRunner1 is ApplicationArguments key : (key1)   ApplicationArguments value : ([测试3])
order value is 3   。MyApplicationRunner1 is ApplicationArguments key : (key2)   ApplicationArguments value : ([测试4])
order value is 4   。MyCommandLineRunner1 run.  get args : [测试1, 测试2, --key1=测试3, --key2=测试4]
对比
  • 两个都是在容器启动成功后的最后一步回调
  • CommandLineRunner的参数是最原始的参数,没有做任何处理。ApplicationRunner的参数是ApplicationArguments,是对原始参数做了进一步的封装。
  • ApplicationRunner只对--key=value这种形式做解析,CommandLineRunner可以获得传递的所有字符串
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA知识总结与分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring Boot缓存预热实战指南
在现代应用程序中,缓存预热是一种常见的优化策略,旨在提高系统的响应速度和性能。特别是在Spring Boot项目启动时,预先将数据加载到缓存系统(如Redis)中,可以有效减少首次请求的延迟。本文将探讨在Spring Boot项目启动后,如何实现缓存预热的不同方案。
用户11397231
2025/06/02
520
Spring Boot缓存预热实战指南
springBoot学习(二)配置环境动态切换和部分注解的运用
建立第一个配置文件(springBoot默认读取的文件)application.properties
乱敲代码
2019/05/30
1.1K0
SpringBoot的多种事件监听机制
  1.由于触发阶段在于准备容器的时候,所以添加@Component注解是不会起作用的,应为@Component注解需要在容器刷新时候才会起到作用。
忧愁的chafry
2022/10/30
5150
springBoot学习(三)springBoot事件监听和部分注解的运用
1.springBoot启动类会使用@SpringBootApplication 2.点进入源代码发现改注解是一个复合注解,由好几个注解共同组合而成
乱敲代码
2019/05/30
5110
springBoot学习(一)建立项目与读取配置文件
Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。
乱敲代码
2019/05/30
1.7K0
【愚公系列】2023年10月 Java教学课程 168-SpringBoot事件监听
SpringBoot事件监听器是一种机制,可以监听应用程序中的事件和状态变化。它可以让开发人员在应用程序启动、关闭、失败或者其他事件发生时,接收到通知并执行相应的操作。SpringBoot提供了很多种事件监听器,如应用程序启动事件、应用程序关闭事件、Web服务器启动事件、Web服务器关闭事件等。开发人员可以通过实现特定的监听器接口并注册到SpringBoot中,来监听这些事件的触发并执行相应的操作。
愚公搬代码
2025/05/28
900
【愚公系列】2023年10月 Java教学课程 168-SpringBoot事件监听
20-SpringBoot事件监听
③监听器:Listener,实现 java.util.EventListener 接口 的对象
Devops海洋的渔夫
2022/03/23
2980
20-SpringBoot事件监听
springBoot学习(五)springBoot自定义banner与web开发
通过 springBootTestRun.setBannerMode(Banner.Mode.OFF);
杨小杰
2019/07/04
7620
springBoot学习(五)springBoot自定义banner与web开发
SpringBoot各类扩展点详解
  上篇文章我们深入分析了SpringBoot的一站式启动流程。然后我们知道SpringBoot的主要功能都是依靠它内部很多的扩展点来完成的,那毋容置疑,这些扩展点是我们应该深入了解的,那么本次且听我一一道来SpringBoot的各类扩展点。
阿豪聊干货
2018/08/09
1.7K0
【SpringBoot】19、SpringBoot中实现启动任务
我们在项目中会用到项目启动任务,即项目在启动的时候需要做的一些事,例如:数据初始化、获取第三方数据等等,那么如何在SpringBoot 中实现启动任务,一起来看看吧
全栈程序员站长
2022/11/09
6250
【SpringBoot】19、SpringBoot中实现启动任务
CommandLineRunner与ApplicationRunner接口的使用及源码解析
我们在使用SpringBoot搭建项目的时候,如果希望在项目启动完成之前,能够初始化一些操作,针对这种需求,可以考虑实现如下两个接口(任一个都可以)
猿天地
2019/07/23
1.2K0
CommandLineRunner与ApplicationRunner接口的使用及源码解析
深入剖析Springboot启动原理的底层源码,再也不怕面试官问了!
Spring Boot的配置类;标注在某个类上,表示一个类提供了Spring Boot应用程序
全栈程序员站长
2022/09/06
5860
深入剖析Springboot启动原理的底层源码,再也不怕面试官问了!
Spring Boot中初始化资源的几种方式
  假设有这么一个需求,要求在项目启动过程中,完成线程池的初始化,加密证书加载等功能,你会怎么做?如果没想好答案,请接着往下看。今天介绍几种在Spring Boot中进行资源初始化的方式,帮助大家解决和回答这个问题。
happyJared
2018/09/20
1.6K0
Spring Boot中初始化资源的几种方式
Spring Boot 定义系统启动任务,你会几种方式?
在Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行,这里,容易想到web基础中的三大组件( Servlet、Filter、Listener )之一 Listener ,这种情况下,一般定义一个 ServletContextListener,然后就可以监听到项目启动和销毁,进而做出相应的数据初始化和销毁操作,例如下面这样:
用户5927304
2019/07/30
5330
Spring Boot 定义系统启动任务,你会几种方式?
Spring Boot+Vue开发实战_有关理解的图片带字
来自面试官发自内审深处的灵魂拷问:“说一下springboot的启动流程”; 一脸懵逼的面试者:“它简化了spring的配置,主要是因为有自动装配的功能,并且可以直接启动,因为它内嵌了tomcat容器”; 面试官:“嗯, 没错,这是 它的一些概念,你还没回答我的问题,它是怎么启动的,启懂时都经过了哪些东西?”; 一脸懵逼的面试者:“额~~~不知道额····,我用的很熟练,但是不知道它里面做了哪些事情!”; 面试官:“了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路更上一层楼,这些底层的东西你是必须要会的,行吧,你回去等消息吧!” 面试者:↓
全栈程序员站长
2022/09/25
4430
Spring Boot+Vue开发实战_有关理解的图片带字
面试官:SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。
磊哥
2024/01/20
9290
面试官:SpringBoot如何实现缓存预热?
SpringBoot启动配置原理
# SpringBoot启动配置原理 几个重要的事件回调机制 配置在META-INF/spring.factories ApplicationContextInitializer SpringApplicationRunListener 只需要放在ioc容器中 ApplicationRunner CommandLineRunner 启动流程: 1、创建SpringApplication对象 initialize(sources); private void initialize(Object[] sourc
程序员阿杜
2021/03/16
3300
SpringBoot启动扩展应用:干预优化+加快启动时间(干货典藏版)
这些干预步骤可以在Spring Boot应用程序启动和停止完成后进行,从而实现更灵活的配置和初始化。
程序员蜗牛
2024/03/01
7890
SpringBoot启动扩展应用:干预优化+加快启动时间(干货典藏版)
一张图帮你记忆,Spring Boot 应用在启动阶段执行代码的几种方式
有时候我们需要在应用启动时执行一些代码片段,这些片段可能是仅仅是为了记录 log,也可能是在启动时检查与安装证书 ,诸如上述业务要求我们可能会经常碰到
用户4172423
2019/12/31
2K0
Spring Boot - ApplicationRunner && CommandLineRunner扩展接口
如果有多个CommandLineRunner,可以利用@Order来进行排序, 按照@Order中的value值从小到大依次执行。
小小工匠
2022/12/09
7400
Spring Boot - ApplicationRunner && CommandLineRunner扩展接口
推荐阅读
相关推荐
Spring Boot缓存预热实战指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验