最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

焦点播报:Spring IOC官方文档学习笔记(十四)之ApplicationContext的其他功能

来源:博客园


(资料图片)

1.使用MessageSource

(1) 有时,我们的项目可能会面临国际化需求,例如:对不同国家的人,我们需返回不同语言的消息,而java本身已经给我们提供了ResourceBundle类实现国际化的需求,如下

//在resources目录下,新建两个配置文件,分别为message_en_us.properties和message_zh_cn.properties,内容如下//message_en_us.properties文件中配置如下country=us//message_zh_cn.properties文件中配置如下,注意对中文使用unicode编码country=\u4e2d\u56fd//现在,我们希望我们的项目在不同的国家返回不同的country信息,那么就可以使用ResourceBundle类了,如下public static void main(String[] args) {    //使用ResourceBundle加载的文件都必须放置在resources根目录下,因此我们的message_en_us.properties和message_zh_cn.properties文件都位于resources根目录,而且这些文件都必须按照${name}_${language}_${region}的方式来命名,因为这种命名方式正好能对应ResourceBundle.getBundle()方法中的参数,例如ResourceBundle.getBundle("message", new Locale("zh", "cn")),其中,message对应${name},zh对应${language},cn对应${region},即ResourceBundle.getBundle("message", new Locale("zh", "cn"))这个方法会读取我们的message_zh_cn.properties配置文件,这样我们就可以根据不同的参数来读取不同的文件,达到国际化的目的    //未指定它的Locale,因此java获取它当前所在的地区,为cn    ResourceBundle DefaultBundle = ResourceBundle.getBundle("message");    System.out.println(DefaultBundle.getString("country"));    //指定地区为cn    ResourceBundle cnBundle = ResourceBundle.getBundle("message", new Locale("zh","cn"));    System.out.println(cnBundle.getString("country"));    //指定地区为us    ResourceBundle uSbundle = ResourceBundle.getBundle("message", new Locale("en","us"));    System.out.println(uSbundle.getString("country"));}//打印结果如下,通过ResourceBundle实现了国际化中国中国us

(2) Spring提供了MessageSource来帮助我们实现国际化功能,具体的使用方法同jdk中的ResourceBundle,如下

//在resources目录下,新建两个配置文件,分别为message_en.properties和message_zh.properties,内容如下//message_en.properties文件中配置如下country=us//message_zh.properties文件中配置如下country=中国                                                                                    message                                                                    UTF-8                    //ApplicationContext继承了MessageSource接口MessageSource messageSource = new ClassPathXmlApplicationContext("beans.xml");//指定不同的语言,来获取不同消息String zh = messageSource.getMessage("country", null, Locale.CHINESE);System.out.println(zh);String en = messageSource.getMessage("country", null, Locale.ENGLISH);System.out.println(en);//启动容器,输出如下中国us

(3) Spring的MessageSource还提供了占位符功能,来进行消息内容的填充,如下例所示

//向message_zh.properties中添加配置项如下,{0}表示第一个占位符,还有{1},{2}等等,以此类推argument=we need {0}//main函数MessageSource messageSource = new ClassPathXmlApplicationContext("beans.xml");                                                     //Object[]指定向占位符填充的内容String argument = messageSource.getMessage("argument", new Object[]{"蛋糕"}, Locale.CHINESE);System.out.println(argument);//启动后,打印如下we need 蛋糕

2.标准和自定义事件

(1) Spring中的事件是通过ApplicationEvent类和ApplicationListener接口提供的,如果一个bean实现了ApplicationListener接口,那么每当一个ApplicationEvent发布到Spring中时,都会通知该bean

(2) Spring中内置事件

事件说明
ContextRefreshedEvent容器初始化或刷新时(refresh)时发布该事件
ContextStartedEvent通过调用ConfigurationApplicationContext接口中的start()方法启动容器时发布该事件
ContextStoppedEvent通过调用ConfigurationApplicationContext接口中的stop()方法停止容器时发布该事件
ContextClosedEvent通过调用ConfigurationApplicationContext接口中的close()方法或jvm关闭钩子关闭容器时发布该事件
RequestHandledEvent适用于使用了DispatcherServlet的web环境中,在请求完成后发布该事件,用于告知所有的bean已经为http请求提供了服务
ServletRequestHandledEventRequestHandledEvent的子类,其中添加了Servlet特定信息

(3) 示例如下

//现在假设有一个用户注册事件,每当一个用户注册后,进行相应的其他操作(如发送邮件等等)//自定义事件,需继承ApplicationEventpublic class RegisterEvent extends ApplicationEvent {    private String username;    public RegisterEvent(Object source,String username) {        super(source);        this.username = username;    }    public String getUsername() {        return username;    }}//使用ApplicationEventPublisher中的publishEvent()方法来向容器中发布一个事件@Servicepublic class RegisterService implements ApplicationEventPublisherAware {    private ApplicationEventPublisher publisher;    @Override    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {        this.publisher = applicationEventPublisher;    }    //publishEvent()方法会阻塞,直到所有的监听器都完成了对事件的处理    public void finishRegister(String username) {        this.publisher.publishEvent(new RegisterEvent(this, username));    }}//实现ApplicationListener接口,实现某种类型事件的监听者@Componentpublic class RegisterLister implements ApplicationListener {    //每当有一个RegisterEvent事件发布后,都会触发该回调    @Override    public void onApplicationEvent(RegisterEvent registerEvent) {        System.out.println("用户:" + registerEvent.getUsername() + "完成注册...");        //do other things,such as send emails    }}//mainConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext("cn.example.spring");String username ="zpc";ctx.getBean(RegisterService.class).finishRegister(username);//启动后,容器打印如下,可见Spring使用了观察者模式,来实现了一个事件发布与订阅的功能用户:zpc完成注册...

关键词: