Spring FrameWork从入门到NB - ApplicationContext

news/2024/10/23 22:23:34/

先看一下ApplicationContext的类结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maqTZDw5-1688910614392)(/img/bVc8BnW)]

可知:ApplicationContext是BeanFactory,所以具有BeanFactory的能力:初始化Spring容器(细节下一篇文章分析),除此之外,ApplicaitonContext还具有如下能力:

  1. MessageSource接口提供的i18n能力。
  2. ResourceLoader接口提供的资源文件访问能力。
  3. ApplicationListener接口提供的事件发布及监听能力。
  4. HierarchicalBeanFactory提供的能力。

今天主要关注前3项。

i18n能力

即使不是国际化项目,i18n也很实用,比如项目中的提示信息或错误信息的管理,实在是见过太多项目对错误信息的放任不管,其实提示信息或者错误信息是系统与用户交互的重要组成部分,有必要认真对待:i18n就是一个选择。

ApplicationContext通过MessageSource接口提供了i18n能力,简单易用。

Spring提供了MessageSource的3个实现:ResourceBundleMessageSource, ReloadableResourceBundleMessageSource和 StaticMessageSource。我们就以ResourceBundleMessageSource举例。

我们知道使用i18n需要以下步骤:

  1. 创建property文件,定义message
  2. 创建MessageSource加载propperty文件
  3. 通过MessageSource获取property文件定义的message

下面我们以xml和注解两种方式举例。

1. 创建property文件

创建property文件是通用的,两种方式无区别,所以我们首先创建property文件。

为了支持中文,我们需要把项目的文件编码方式设置为UTF-8、property文件的编码方式选择为UTF-8,并且一定勾选native-to-accii这一选项,否则会出现中文乱码:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e5rYRuqm-1688910614395)(/img/bVc8BBs)]

然后在resources目录下创建一个myMessage的、包含en和zh两个语言resource Bundle文件,创建完成后如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IwEwlsES-1688910614396)(/img/bVc8BBA)]
打开myMessage_en.propperties文件,输入:

msg=this is {0}

打开myMessage_zh.properties文件输入:

msg=我其实就是要汉语的提示信息 {0}

这个时候到classpath下看一下myMessage_zh.properties:

msg=\u7EC8\u4E8E\u53EF\u4EE5\u6C49\u5B57\u4E86\u554A {0}

可以看到是转换为accii码以后的文件了,这个就是native-to-ascii选项的作用,如果这里看到的依然是汉字,最终出来的大概率是乱码。

好了,properties文件创建好了。

xml方式实现i18n

还是用我们以前的例子,在mySpring.xml文件中加入如下配置信息,把ResourceBundleMessageSource类加载到Spring容器中并指定配置文件名称为myMessage:

  <bean id="messageSource"class="org.springframework.context.support.ResourceBundleMessageSource"><property name="basenames"><list><value>myMessage</value></list></property></bean>

然后在xml启动类中加入对message的调用代码:

public class AppByXML {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("mySpring.xml");String msg = applicationContext.getMessage("msg",new Object[]{"汉字"},"default msg", Locale.CHINESE);System.out.println("msg:"+msg);}
}

执行启动类:

msg:我其实就是要汉语的提示信息 汉字

然后修改一下启动类,让他调用en配置文件:

public class AppByXML {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("mySpring.xml");String msg = applicationContext.getMessage("msg",new Object[]{"english"},"default msg", Locale.ENGLISH);System.out.println("msg:"+msg);}

执行启动类:

msg:this is english

xml配置方式下调用applicationContext的i18n功能成功!

注解方式

只要把MessageSource注入到Spring容器中就可以,所以,在MyConfiguration文件中:

@Configuration()
@ComponentScan(value={"springTest"})
public class MyConfiguration {@Beanpublic MessageSource messageSource(){ResourceBundleMessageSource rbm = new ResourceBundleMessageSource();rbm.setBasenames("myMessage");return rbm;}
}

启动类:

public class App {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class);
//        (ResourceBundleMessageSource)applicationContextString msg = applicationContext.getMessage("msg",new Object[]{"test"},"default msg", Locale.ENGLISH);System.out.println("msg:"+msg);
}

执行启动类就OK。

事件监听

Spring的事件监听机制遵循订阅者模式,整个事件监听框架由以下3部分组成:

  1. 事件:ApplicationEvent接口实现
  2. 事件发布:由ApplicationEventPublisher接口完成。
  3. 事件监听:ApplicationListener接口负责。

由于ApplicationContext实现了ApplicationEventPublisher接口,所以他天生就是事件发布器。

Spring4.2之后,加强了对事件监听机制的支持,可以支持通过注解发布和监听事件,而且不仅支持发布ApplicationEvent事件,还可以支持普通对象(不需要实现ApplicationEvent接口)的事件发布。

发布未实现ApplicationEvent事件后,ApplicationContext会自动封装其为PayloadApplicationEvent:

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<>(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}}

原始对象被封装在PayloadApplicationEvent的payload属性中,在监听器中可以通过payload获取。

允许的情况下,还是建议发布ApplicationEvent事件,这样的话可以实现有针对性的监听器、专门监听相应事件,这种情况下监听器的onApplicationEvent方法中的事件就是类型安全的、不需要检查和强制向下转换。

监听器必须要作为bean注入到Spring容器中,否则的话是监听不到ApplicationContext发布的事件的。

Spring的监听器可以有以下两种实现方式:

  1. 实现ApplicationListener接口
  2. 监听方法上使用@EventListener注解

应用层发布事件是需要ApplicationContext对象的,所以,在应用层需要获取到ApplicationContext对象,以什么样的方式获取比较方便呢?

自然而然,回想以下前面学习过的内容Spring FrameWork从入门到NB - 定制Bean,其中提到ApplicationContextAware接口:“ApplicationContextAware接口提供了一个机会,让你从普通的Spring Bean中可以获得到创建他的ApplicationContext。”这就够了!

异步监听器

***需要特别注意的是,默认情况下,事件监听器的处理逻辑和事件发布的主逻辑是处于同一个线程中同步执行的。***好处是事件监听逻辑可以和事件发布逻辑共享事务(如果存在事务、而且业务有要求的话)。

但如果我们有特殊需求,想要异步事件监听器,该怎么实现呢?

Spring那么NB,实现方式当然非常简单:在Listner上加@Async注解就可以。注意需要在配置类上增加@EnableAsync注解,否则@Async不会生效。

监听事件排序

依然是要在监听器上做文章,在监听器ApplicationListener上、或者@EnentLister注解方法上使用@Order注解。
上一篇 Spring FrameWork从入门到NB - Environment Abstraction


http://www.ppmy.cn/news/797075.html

相关文章

文章同步--飞鹤官方商城加密逆向分析(小程序)、蝉管家滑块加密参数逆向分析

飞鹤官方商城加密逆向分析&#xff08;小程序&#xff09; 蝉管家滑块加密参数逆向分析

数据集 VOC转YOLO格式

一、xml转换为txt import os.path import xml.etree.ElementTree as ET import os import random # class_names [palm, stone, scissor, awesome, heartB, OK, ROCK, one, swear, thanks, heartA, # heartC, good, bad, pray, call, take_picture, salute] c…

web 页面布局:(三)position 坐标系布局

web 页面布局&#xff1a;&#xff08;三&#xff09;position 坐标系布局 页面坐标系position 设置fixedrelativeabsolutesticky 应用场景 页面坐标系 因为所有文本内容&#xff0c;是从左向右读&#xff0c;自上而下读&#xff0c;和书写习惯&#xff0c;读书习惯一致&#…

小米路由器局域网设备ping不通

问题 两台电脑在同一个局域网内&#xff0c;都连接上小米路由器&#xff0c;我发现电脑部署的服务局域网设备都访问不到&#xff0c;甚至ping不到&#xff0c;排除了防火墙问题&#xff0c;最终发现是路由器一个设置导致的。 解决 将原来的混合加密&#xff0c;更换为强加密…

opencv报错 ValueError: too many values to unpack (expected 2)

改为&#xff1a; binary,contours,hierarch cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 原代码&#xff1a;contours, _ cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 在pycharm上运行没问题&#xff0c;在树霉派上会…

21-注册中心与配置中心Nacos

已经使用过了Spring cloud提供的Geteway、openFeign。 1、注册中心与配置中心 1.1、注册中心 相当于通讯录,让应用之间相互认识。 用途: 实例的健康检查。 路由转发:为了控制成本,会对机器做动态扩容,此时IP就不固定了。 远程调用。 1.2、配置中心 动态修改线上的配…

l7sa008b故障代码_华硕主板故障维代码指南

华硕主板根据故障代码维修指南 来源 : 电脑软硬件应用网 作者 : 网络收集 更新时间 : 12-29 点击 : 15 次 ( 1 ) POWER,POWEROK,RESET,CLK,REQ#,A20M#,M/IO# 信号错误; ( 2 ) HA,HD,AD,SA 信号错误; ( 3 )插 PCI 卡引起 00 ,去掉 PCI 卡 OK: PCI 总线 GNT 开路 ; ( 4 ) 地址…

阿里云轻量应用服务器和云服务器ECS有什么区别?

阿里云服务器ECS和轻量应用服务器有什么区别&#xff1f;云服务器ECS是明星级云服务器&#xff0c;轻量应用服务器可以理解为简化版的云服务器ECS&#xff0c;轻量适用于单机应用&#xff0c;云服务器ECS适用于集群类高可用高容灾应用&#xff0c;阿里云百科来详细说下阿里云轻…