首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring之ClassPathXmlApplicationContext

Spring之ClassPathXmlApplicationContext

作者头像
叔牙
发布2020-11-19 17:42:08
8790
发布2020-11-19 17:42:08
举报

Spring之ClassPathXmlApplicationContext

听说转发文章

会给你带来好运

1

介绍

简单地说,Spring Framework核心是一个用于管理bean的IoC容器。

Spring中有两种基本类型的容器 - Bean Factory和Application Context。 前者提供了基本功能,在此介绍; 后者是前者的超集,是最广泛使用的。

ApplicationContext是org.springframework.context包中的一个接口,它有几个实现,ClassPathXmlApplicationContext就是其中之一。

在本文中,我们将重点介绍ClassPathXmlApplicationContext提供的有用功能。

2

基本用法

2.1 初始化容器和管理Bean

ClassPathXmlApplicationContext可以从类路径加载XML配置并管理其bean。

我们有一个Student类:

  1. public class Student {
  2. private int no;
  3. private String name;
  4. // standard constructors, getters and setters
  5. }

我们在classpathxmlapplicationcontext-example.xml中配置Student bean并将其添加到类路径中:

  1. <beans ...>
  2. <bean id="student" class="com.baeldung.applicationcontext.Student">
  3. <property name="no" value="15"/>
  4. <property name="name" value="Tom"/>
  5. </bean>
  6. </beans>

现在我们可以使用ClassPathXmlApplicationContext来加载XML配置并获取Student bean:

  1. @Test
  2. public void testBasicUsage() {
  3. ApplicationContext context
  4. = new ClassPathXmlApplicationContext(
  5. "classpathxmlapplicationcontext-example.xml");
  6. Student student = (Student) context.getBean("student");
  7. assertThat(student.getNo(), equalTo(15));
  8. assertThat(student.getName(), equalTo("Tom"));
  9. Student sameStudent = context.getBean("student", Student.class);
  10. assertThat(sameStudent.getNo(), equalTo(15));
  11. assertThat(sameStudent.getName(), equalTo("Tom"));
  12. }

2.2 多个XML配置

有时我们想使用几个XML配置来初始化Spring容器。 在这种情况下,我们只需要在构造ApplicationContext时添加几个配置位置:

  1. ApplicationContext context
  2. = new ClassPathXmlApplicationContext("ctx.xml", "ctx2.xml");

3

附加功能

3.1 优雅关闭Spring IOC容器

当我们在Web应用程序中使用Spring IoC容器时,Spring的基于Web的ApplicationContext实现将在关闭应用程序时正常关闭容器,但如果我们在非Web环境中使用它,

例如独立的桌面应用程序,我们我们必须自己向JVM注册一个关闭钩子,以确保Spring IoC容器正常关闭并调用destroy方法释放资源。

在Student类中添加一个destroy()方法:

  1. public void destroy() {
  2. System.out.println("Student(no: " + no + ") is destroyed");
  3. }

我们现在可以将此方法配置为student bean的destroy方法:

  1. <beans ...>
  2. <bean id="student" class="com.baeldung.applicationcontext.Student"
  3. destroy-method="destroy">
  4. <property name="no" value="15"/>
  5. <property name="name" value="Tom"/>
  6. </bean>
  7. </beans>

我们现在将注册一个关闭钩子:

  1. @Test
  2. public void testRegisterShutdownHook() {
  3. ConfigurableApplicationContext context
  4. = new ClassPathXmlApplicationContext(
  5. "classpathxmlapplicationcontext-example.xml");
  6. context.registerShutdownHook();
  7. }

当我们运行测试方法时,我们可以看到调用destroy()方法。

3.2 使用MessageSource进行国际化

ApplicationContext接口扩展了MessageSource接口,因此提供了国际化功能。

ApplicationContext容器在其初始化时自动搜索MessageSource bean,并且bean必须命名为messageSource。

以下是使用MessageSource使用不同语言的示例。

首先,让我们将一个会话目录添加到类路径中,并将两个文件添加到会话目录中:dialog_en.properties和dialog_zh_CN.properties。

dialog_en.properties:

  1. hello=hello
  2. you=you
  3. thanks=thank {0}

dialog_zh_CN.properties:

  1. hello=\\u4f60\\u597d
  2. you=\\u4f60
  3. thanks=\\u8c22\\u8c22{0}

在classpathxmlapplicationcontext-internationalization.xml中配置messageSource bean:

  1. <beans ...>
  2. <bean id="messageSource"
  3. class="org.springframework.context.support.ResourceBundleMessageSource">
  4. <property name="basenames">
  5. <list>
  6. <value>dialog/dialog</value>
  7. </list>
  8. </property>
  9. </bean>
  10. </beans>

然后,让我们使用MessageSource获取不同语言的对话框:

  1. @Test
  2. public void testInternationalization() {
  3. MessageSource resources
  4. = new ClassPathXmlApplicationContext(
  5. "classpathxmlapplicationcontext-internationalization.xml");
  6. String enHello = resources.getMessage(
  7. "hello", null, "Default", Locale.ENGLISH);
  8. String enYou = resources.getMessage(
  9. "you", null, Locale.ENGLISH);
  10. String enThanks = resources.getMessage(
  11. "thanks", new Object[] { enYou }, Locale.ENGLISH);
  12. assertThat(enHello, equalTo("hello"));
  13. assertThat(enThanks, equalTo("thank you"));
  14. String chHello = resources.getMessage(
  15. "hello", null, "Default", Locale.SIMPLIFIED_CHINESE);
  16. String chYou = resources.getMessage(
  17. "you", null, Locale.SIMPLIFIED_CHINESE);
  18. String chThanks = resources.getMessage(
  19. "thanks", new Object[] { chYou }, Locale.SIMPLIFIED_CHINESE);
  20. assertThat(chHello, equalTo("你好"));
  21. assertThat(chThanks, equalTo("谢谢你"));
  22. }

4

ApplicationContext引用

有时我们需要在由它管理的bean中获取ApplicationContext的引用,我们可以使用ApplicationContextAware或@Autowired来执行此操作。

让我们看看如何使用ApplicationContextAware:

  1. public class Course {
  2. private String name;
  3. // standard constructors, getters and setters
  4. }

我们有一个Teacher类,它根据容器的bean组装它的课程:

  1. public class Teacher implements ApplicationContextAware {
  2. private ApplicationContext context;
  3. private List<Course> courses = new ArrayList<>();
  4. @Override
  5. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  6. this.context = applicationContext;
  7. }
  8. @PostConstruct
  9. public void addCourse() {
  10. if (context.containsBean("math")) {
  11. Course math = context.getBean("math", Course.class);
  12. courses.add(math);
  13. }
  14. if (context.containsBean("physics")) {
  15. Course physics = context.getBean("physics", Course.class);
  16. courses.add(physics);
  17. }
  18. }
  19. // standard constructors, getters and setters
  20. }

在classpathxmlapplicationcontext-example.xml中配置课程bean和教师bean:

  1. <beans ...>
  2. <bean id="math" class="com.baeldung.applicationcontext.Course">
  3. <property name="name" value="math"/>
  4. </bean>
  5. <bean name="teacher" class="com.baeldung.applicationcontext.Teacher"/>
  6. </beans>

然后,测试课程属性的注入:

  1. @Test
  2. public void testApplicationContextAware() {
  3. ApplicationContext context
  4. = new ClassPathXmlApplicationContext(
  5. "classpathxmlapplicationcontext-example.xml");
  6. Teacher teacher = context.getBean("teacher", Teacher.class);
  7. List<Course> courses = teacher.getCourses();
  8. assertThat(courses.size(), equalTo(1));
  9. assertThat(courses.get(0).getName(), equalTo("math"));
  10. }

除了实现ApplicationContextAware接口之外,使用@Autowired注释也具有相同的效果。

将Teacher类更改为:

  1. public class Teacher {
  2. @Autowired
  3. private ApplicationContext context;
  4. private List<Course> courses = new ArrayList<>();
  5. @PostConstruct
  6. public void addCourse() {
  7. if (context.containsBean("math")) {
  8. Course math = context.getBean("math", Course.class);
  9. courses.add(math);
  10. }
  11. if (context.containsBean("physics")) {
  12. Course physics = context.getBean("physics", Course.class);
  13. courses.add(physics);
  14. }
  15. }
  16. // standard constructors, getters and setters
  17. }

然后运行测试用例,我们可以看到结果是一样的。

总结

ApplicationContext是一个Spring容器,与BeanFactory相比具有更多特定于企业应用的功能,而ClassPathXmlApplicationContext是其最常用的实现之一。

因此,在本文中,我们介绍了ClassPathXmlApplicationContext的几个方面,包括其基本用法,关闭注册功能,国际化功能以及获取其引用。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PersistentCoder 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档