
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类:
public class Student { private int no; private String name; // standard constructors, getters and setters }我们在classpathxmlapplicationcontext-example.xml中配置Student bean并将其添加到类路径中:
<beans ...> <bean id="student" class="com.baeldung.applicationcontext.Student"> <property name="no" value="15"/> <property name="name" value="Tom"/> </bean> </beans>现在我们可以使用ClassPathXmlApplicationContext来加载XML配置并获取Student bean:
@Test public void testBasicUsage() { ApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); Student student = (Student) context.getBean("student"); assertThat(student.getNo(), equalTo(15)); assertThat(student.getName(), equalTo("Tom")); Student sameStudent = context.getBean("student", Student.class); assertThat(sameStudent.getNo(), equalTo(15)); assertThat(sameStudent.getName(), equalTo("Tom")); }2.2 多个XML配置
有时我们想使用几个XML配置来初始化Spring容器。 在这种情况下,我们只需要在构造ApplicationContext时添加几个配置位置:
ApplicationContext context = new ClassPathXmlApplicationContext("ctx.xml", "ctx2.xml");3
附加功能
3.1 优雅关闭Spring IOC容器
当我们在Web应用程序中使用Spring IoC容器时,Spring的基于Web的ApplicationContext实现将在关闭应用程序时正常关闭容器,但如果我们在非Web环境中使用它,
例如独立的桌面应用程序,我们我们必须自己向JVM注册一个关闭钩子,以确保Spring IoC容器正常关闭并调用destroy方法释放资源。
在Student类中添加一个destroy()方法:
public void destroy() { System.out.println("Student(no: " + no + ") is destroyed"); }我们现在可以将此方法配置为student bean的destroy方法:
<beans ...> <bean id="student" class="com.baeldung.applicationcontext.Student" destroy-method="destroy"> <property name="no" value="15"/> <property name="name" value="Tom"/> </bean> </beans>我们现在将注册一个关闭钩子:
@Test public void testRegisterShutdownHook() { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); context.registerShutdownHook(); }当我们运行测试方法时,我们可以看到调用destroy()方法。
3.2 使用MessageSource进行国际化
ApplicationContext接口扩展了MessageSource接口,因此提供了国际化功能。
ApplicationContext容器在其初始化时自动搜索MessageSource bean,并且bean必须命名为messageSource。
以下是使用MessageSource使用不同语言的示例。
首先,让我们将一个会话目录添加到类路径中,并将两个文件添加到会话目录中:dialog_en.properties和dialog_zh_CN.properties。
dialog_en.properties:
hello=hello you=you thanks=thank {0}dialog_zh_CN.properties:
hello=\\u4f60\\u597d you=\\u4f60 thanks=\\u8c22\\u8c22{0}在classpathxmlapplicationcontext-internationalization.xml中配置messageSource bean:
<beans ...> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>dialog/dialog</value> </list> </property> </bean> </beans>然后,让我们使用MessageSource获取不同语言的对话框:
@Test public void testInternationalization() { MessageSource resources = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-internationalization.xml"); String enHello = resources.getMessage( "hello", null, "Default", Locale.ENGLISH); String enYou = resources.getMessage( "you", null, Locale.ENGLISH); String enThanks = resources.getMessage( "thanks", new Object[] { enYou }, Locale.ENGLISH); assertThat(enHello, equalTo("hello")); assertThat(enThanks, equalTo("thank you")); String chHello = resources.getMessage( "hello", null, "Default", Locale.SIMPLIFIED_CHINESE); String chYou = resources.getMessage( "you", null, Locale.SIMPLIFIED_CHINESE); String chThanks = resources.getMessage( "thanks", new Object[] { chYou }, Locale.SIMPLIFIED_CHINESE); assertThat(chHello, equalTo("你好")); assertThat(chThanks, equalTo("谢谢你")); }4
ApplicationContext引用
有时我们需要在由它管理的bean中获取ApplicationContext的引用,我们可以使用ApplicationContextAware或@Autowired来执行此操作。
让我们看看如何使用ApplicationContextAware:
public class Course { private String name; // standard constructors, getters and setters }我们有一个Teacher类,它根据容器的bean组装它的课程:
public class Teacher implements ApplicationContextAware { private ApplicationContext context; private List<Course> courses = new ArrayList<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } @PostConstruct public void addCourse() { if (context.containsBean("math")) { Course math = context.getBean("math", Course.class); courses.add(math); } if (context.containsBean("physics")) { Course physics = context.getBean("physics", Course.class); courses.add(physics); } } // standard constructors, getters and setters }在classpathxmlapplicationcontext-example.xml中配置课程bean和教师bean:
<beans ...> <bean id="math" class="com.baeldung.applicationcontext.Course"> <property name="name" value="math"/> </bean> <bean name="teacher" class="com.baeldung.applicationcontext.Teacher"/> </beans>然后,测试课程属性的注入:
@Test public void testApplicationContextAware() { ApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); Teacher teacher = context.getBean("teacher", Teacher.class); List<Course> courses = teacher.getCourses(); assertThat(courses.size(), equalTo(1)); assertThat(courses.get(0).getName(), equalTo("math")); }除了实现ApplicationContextAware接口之外,使用@Autowired注释也具有相同的效果。
将Teacher类更改为:
public class Teacher { @Autowired private ApplicationContext context; private List<Course> courses = new ArrayList<>(); @PostConstruct public void addCourse() { if (context.containsBean("math")) { Course math = context.getBean("math", Course.class); courses.add(math); } if (context.containsBean("physics")) { Course physics = context.getBean("physics", Course.class); courses.add(physics); } } // standard constructors, getters and setters }然后运行测试用例,我们可以看到结果是一样的。
总结
ApplicationContext是一个Spring容器,与BeanFactory相比具有更多特定于企业应用的功能,而ClassPathXmlApplicationContext是其最常用的实现之一。
因此,在本文中,我们介绍了ClassPathXmlApplicationContext的几个方面,包括其基本用法,关闭注册功能,国际化功能以及获取其引用。
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!