Spring源码系列(补充):详解ApplicationContext

前言

在之前的文章中,我们已经对Spring源码中的一些核心概念进行了分析。由于篇幅限制,我们并没有详细解释ApplicationContext类所继承的父接口及其作用。因此,本文将单独为ApplicationContext进行详细说明,包括其继承的父接口及其作用。

ApplicationContext父接口

MessageSource

大家应该都比较熟悉MessageSource,它用于国际化,许多项目都会使用它。使用MessageSource的基本步骤如下:

 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

 String message = applicationContext.getMessage("test", null, new Locale("en"));
 System.out.println(message);

你需要在resources路径下创建相应的语言文件。例如,在本文的代码示例中,我们使用了“en”语言,因此需要创建messages_en.properties文件,其内容如下:

test=b

这样,当我们获取“test”语言时,就会得到“b”。

ResourcePatternResolver

ResourcePatternResolver主要用于获取资源,即资源加载,可以加载某个文件的内容。具体步骤如下:

// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

//		String message = applicationContext.getMessage("test", null, new Locale("en"));
//		System.out.println(message);
		Resource resource = applicationContext.getResource("classpath:spring.properties");
		System.out.println(resource.contentLength());

除此之外,ResourcePatternResolver还有其他用法,例如:

// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

//		String message = applicationContext.getMessage("test", null, new Locale("en"));
//		System.out.println(message);
		Resource resource = applicationContext.getResource("https://www.baidu.com");
		System.out.println(resource.contentLength());
		System.out.println(resource.getURL());
		//还可以获取多个资源
		Resource[] resources = applicationContext.getResources("classpath:com/xiaoyu/*.class");
		Arrays.stream(resources).forEach(System.out::println);

以上只是简单的示例,具体使用方法还需根据实际情况进行调整。

EnvironmentCapable

获取运行时环境可以使用ApplicationContext的getEnvironment方法,具体用法如下:

// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		applicationContext.getEnvironment().getPropertySources().forEach(System.out::println);
		System.out.println("================");
		applicationContext.getEnvironment().getSystemEnvironment().forEach((k, v) -> System.out.println(k + " : " + v));
		System.out.println("================");
		applicationContext.getEnvironment().getSystemProperties().forEach((k, v) -> System.out.println(k + " : " + v));
		System.out.println("================");
		System.out.println(applicationContext.getEnvironment().getProperty("sun.jnu.encoding"));
		System.out.println(applicationContext.getEnvironment().getProperty("xiaoyu"));
@PropertySource("classpath:spring.properties")

注意,可以使用@PropertySource注解将spring.properties添加到运行时环境,然后通过getProperty方法去获取。

ApplicationEventPublisher

ApplicationEventPublisher是一个事件发布器,我们可以通过ApplicationContext来发布一个相应的事件,具体步骤如下:

// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
    //发布自己的事件
		applicationContext.publishEvent(new MyEvent("xiaoyu"));

定义自己的事件:

public class MyEvent extends ApplicationEvent {

	private String message;

	public MyEvent(String message) {
		super(message);
		this.message = message;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

创建一个事件监听器,可以监听所有事件,也可以单独监听自己的事件。如果想要监听所有事件,直接去掉泛型即可。Spring的事件也可以监听到,因此在监听部分需要自己判断是什么事件。具体步骤如下:

@Component
public class MyEventListener implements ApplicationListener<MyEvent> {

	/**
	 * Handle an application event.
	 *
	 * @param event the event to respond to
	 */
	@Override
	public void onApplicationEvent(MyEvent event) {
		if (event instanceof MyEvent) {
			System.out.println(((MyEvent) event).getMessage());
		}
		System.out.println(event);
	}

}

OrderComparator

这里注意下,OrderComparator并不是ApplicationContext的父接口,它是Spring内部提供的一种比较器,用于排序实现了Order接口或者@Order注解的bean。虽然在工作中我们也会用到排序,但单独写一篇文章可能并不必要,因此在这里简单提一下。

他是Spring内部提供的一种比较器,用于排序实现了order接口或者@order注解,首先定义两个具体的bean,具体用法如下:

public class First implements Ordered {

	@Override
	public int getOrder() {
		return 1;
	}
}
public class Second implements Ordered {

	@Override
	public int getOrder() {
		return 2;
	}
}
First first = new First();
		Second second = new Second();
		Arrays.asList(first, second).stream().sorted(OrderComparator.INSTANCE).forEach(System.out::println);

这样就会升序排序,数值越小越在前面,如果使用的是注解形式的@order,则使用下面的实例:

First first = new First();
		Second second = new Second();
		Arrays.asList(first, second).stream().sorted(AnnotationAwareOrderComparator.INSTANCE).forEach(System.out::println);

注意,OrderComparator只适用于实现了Ordered接口或者@Order注解的bean,如果需要对其他类型的对象进行排序,可以使用其他比较器。

结语

至此,Spring的核心概念解析告一段落,但这只是一个开始,后续我们将深入理解Spring的源码。因此,建议仔细查看Spring的核心关键类,对于后续查看Spring源码会非常有帮助。同时,在实际项目中多关注Spring框架,加深对其理解和掌握。
公众号

原文链接:https://www.cnblogs.com/guoxiaoyu/p/17340082.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring源码系列(补充):详解ApplicationContext - Python技术站

(0)
上一篇 2023年4月22日
下一篇 2023年4月22日

相关文章

  • 微信小程序实现表格前后台分页

    下面是微信小程序实现表格前后台分页的完整攻略: 1. 准备工作 安装微信开发者工具 新建小程序项目 安装 wx-server-sdk(用于云函数开发) 2. 前端页面设计 使用 table 标签展示表格 使用 navigator 标签实现分页 先给出一个示例代码: <view> <table> <thead> <tr…

    Java 2023年5月23日
    00
  • 实例讲解Android中SQLiteDatabase使用方法

    首先我们需要了解一下什么是SQLiteDatabase。它是Android系统中实现本地数据库的一种机制,也是Android开发中常用的本地存储方式之一。下面将介绍它的使用方法。 创建或打开数据库 通过以下代码可以创建或打开一个名为“test.db”的数据库,并且返回一个SQLiteDatabase对象。 SQLiteDatabase db = openOr…

    Java 2023年6月16日
    00
  • Maven 打包跳过测试的 5 种方法,应有尽有,还有谁不会!?

    平时开发时的工作的话之主要负责写代码就行了,什么发布项目啊,好吧不是我们干的事。在我们的了解中打包发布项目应该不是一个困难的问题。 对,最简单的方法就行使用直接使用maven插件打包,甚至我们都不需要知道他是怎么实现的,插件能帮我们将项目打包为一个jar包,然后使用java -jar xx.jar就能运行我们的项目。 我们平时使用的在开发中使用的是开发或测试…

    Java 2023年4月19日
    00
  • Java实现mybatis批量插入数据到Oracle

    下面我来详细讲解“Java实现mybatis批量插入数据到Oracle”的完整攻略。 一、项目依赖 在项目的pom.xml文件中添加以下依赖: <!– MyBatis –> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybat…

    Java 2023年5月20日
    00
  • 手动编译并运行Java项目实现过程解析

    手动编译并运行Java项目的过程可以分为以下步骤: 1. 编写Java代码 首先,我们需要编写Java代码。可以使用任何文本编辑器编写Java代码,只需要将代码保存为.java文件即可。例如,我们可以创建一个名为HelloWorld.java的文件,并将以下代码复制到其中: public class HelloWorld { public static vo…

    Java 2023年5月19日
    00
  • JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析

    JSON在Javascript中的使用是非常常见的操作,JSON是一种轻量级的数据格式,非常适合用于数据交互。在Javascript中,我们可以使用两种方式来解析JSON数据,一种是eval函数,另一种是JSON.parse方法。本篇文章将详细解析这两种方式的异同以及使用姿势。 eval函数 eval函数是Javascript中自带的函数,用于执行一段字符串…

    Java 2023年5月26日
    00
  • Spring5学习之基础知识总结

    标题 Spring5 学习之基础知识总结 简介Spring 是一个轻量级的、开源的框架,目的是简化 Java 开发。它处理了应用程序的基础设施,使开发人员可以专注于业务逻辑。在本文中,将会总结 Spring5 的基础知识,包括如何创建 Spring 应用程序、依赖注入、AOP 技术等。 Spring5 应用程序的创建以下是 Spring5 应用程序的创建步骤…

    Java 2023年5月19日
    00
  • Java多线程之synchronized同步代码块详解

    Java多线程之synchronized同步代码块详解 什么是synchronized同步代码块? synchronized 是 Java 中的一个关键字,用来实现多线程的同步。synchronized 有两个作用:一是保证代码块只能由一个线程执行,二是保证该线程执行该代码块期间所需的所有资源都已获取。 具体地说,我们可以使用synchronized关键字来…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部