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 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!