gball个人知识库
首页
基础组件
基础知识
算法&设计模式
  • 操作手册
  • 数据库
  • 极客时间
  • 每日随笔
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 画图工具 (opens new window)
关于
  • 网盘 (opens new window)
  • 分类
  • 标签
  • 归档
项目
GitHub (opens new window)

ggball

后端界的小学生
首页
基础组件
基础知识
算法&设计模式
  • 操作手册
  • 数据库
  • 极客时间
  • 每日随笔
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 画图工具 (opens new window)
关于
  • 网盘 (opens new window)
  • 分类
  • 标签
  • 归档
项目
GitHub (opens new window)
  • 面试

  • 数据库

  • linux

  • node

  • tensorFlow

  • 基础组件

    • mybatis

    • spring

    • 消息队列

    • springboot

      • springboot 深入解析 监听器
      • SpringBoot 在IDEA中实现热部署 (JRebel实用版)
      • springboot三种系统初始化方式解析
        • 1. 第一种 利用 spring.factories
        • 2. 第二种 改变启动类方式
        • 3. 第三种 利用 application.properties
    • tomcat如何工作

    • elasticsearch

  • 基础知识

  • 算法与设计模式

  • 分布式

  • 疑难杂症

  • go学习之旅

  • 极客时间

  • 知识库
  • 基础组件
  • springboot
ggball
2021-01-30

springboot三种系统初始化方式解析

# springboot三种系统初始化方式解析

# 1. 第一种 利用 spring.factories

在资源文件目录建立 spring.factories 文件 存入key-value信息

org.springframework.context.ApplicationContextInitializer=com.zhu.ggball.springboot.initializer.FirstInitializer
1

image-20210118213956051

实现 ApplicationContextInitializer 类

/**
 * @program: springboot
 * @description: 第一种初始化方式
 * @author: ggBall
 * @create: 2021-01-13 09:16
 **/
@Order(1)
public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 1. 获取环境
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        // 2. 构建自己的属性
        HashMap<String, Object> map = new HashMap<>();
        map.put("key1","value1");
        MapPropertySource source = new MapPropertySource("firstInitializer", map);
        // 3. 加入环境属性集中
        environment.getPropertySources().addLast(source);

        System.out.println("firstInitializer start... ");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

原理:

启动类 run方法 执行 SpringApplication 构造函数

/**
	 * Create a new {@link SpringApplication} instance. The application context will load
	 * beans from the specified primary sources (see {@link SpringApplication class-level}
	 * documentation for details. The instance can be customized before calling
	 * {@link #run(String...)}.
	 * @param resourceLoader the resource loader to use
	 * @param primarySources the primary bean sources
	 * @see #run(Class, String[])
	 * @see #setSources(Set)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class));
        // 设置初始化器
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

获取spring工厂实例对象

	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        // 获得 类加载器
		ClassLoader classLoader = getClassLoader();
		// Use names and ensure unique to protect against duplicates
        // 获取 spring.factories key-value对象 存入缓存中
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        // 实例化对象
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        // 根据@Order的value值 排序 越小越靠前
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}
1
2
3
4
5
6
7
8
9
10
11
12
// 创建实例化对象
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
			ClassLoader classLoader, Object[] args, Set<String> names) {
		List<T> instances = new ArrayList<>(names.size());
		for (String name : names) {
			try {
				Class<?> instanceClass = ClassUtils.forName(name, classLoader);
				Assert.isAssignable(type, instanceClass);
				Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
				T instance = (T) BeanUtils.instantiateClass(constructor, args);
				instances.add(instance);
			}
			catch (Throwable ex) {
				throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
			}
		}
		return instances;
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 2. 第二种 改变启动类方式

改变启动类方式

@SpringBootApplication
public class GgballSpringbootInitializerApplication {

    public static void main(String[] args) {

        // 第一种系统初始化方式
         SpringApplication.run(GgballSpringbootInitializerApplication.class, args);

        // 第二种初始化系统方式
//        SpringApplication application = new SpringApplication(GgballSpringbootInitializerApplication.class);
//        SecondInitializer secondInitializer = new SecondInitializer();
//        application.addInitializers(secondInitializer);
//
//        application.run(args);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

实现 ApplicationContextInitializer 类

/**
 * @program: springboot
 * @description: 第二种初始化方式
 * @author: ggBall
 * @create: 2021-01-14 09:17
 **/
// @Order Spring IOC容器中Bean的执行顺序的优先级
@Order(2)
public class SecondInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        // 1. 获取环境
        ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
        // 2. 准备资源map
        HashMap<String, Object> map = new HashMap<>();
        map.put("key2","value2");
        MapPropertySource source = new MapPropertySource("secondInitializer", map);
        // 3. 填入环境
        environment.getPropertySources().addLast(source);

        System.out.println("SecondInitializer ... ");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 3. 第三种 利用 application.properties

利用 application.properties 添加

context.initializer.classes=com.zhu.ggball.springboot.initializer.ThirdInitializer

1
2
实现 ApplicationContextInitializer 类
/**
 * @program: springboot
 * @description: 第三种初始化方式
 * @author: ggBall
 * @create: 2021-01-14 09:17
 **/
// @Order Spring IOC容器中Bean的执行顺序的优先级 默认是最低优先级,值越小优先级越高
@Order(3)
public class ThirdInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        // 1. 获取环境
        ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
        // 2. 准备资源map
        HashMap<String, Object> map = new HashMap<>();
        map.put("key3","value3");
        MapPropertySource source = new MapPropertySource("thirdInitializer", map);
        // 3. 填入环境
        environment.getPropertySources().addLast(source);

        System.out.println("thirdInitializer start ... ");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#java
上次更新: 2025/06/04, 15:06:15
SpringBoot 在IDEA中实现热部署 (JRebel实用版)
简单实现web服务器

← SpringBoot 在IDEA中实现热部署 (JRebel实用版) 简单实现web服务器→

最近更新
01
AIIDE
03-07
02
githubActionCICD实战
03-07
03
windows安装Deep-Live-Cam教程
08-11
更多文章>
Theme by Vdoing
总访问量 次 | 总访客数 人
| Copyright © 2021-2025 ggball | 赣ICP备2021008769号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×

评论

  • 评论 ssss
  • 回复
  • 评论 ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
  • 回复
  • 评论 ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
  • 回复
×