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类:
publicclassStudent{-
privateint no; -
privateString 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:
@Testpublicvoid testBasicUsage(){-
ApplicationContext context -
=newClassPathXmlApplicationContext( -
"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-
=newClassPathXmlApplicationContext("ctx.xml","ctx2.xml");
3
附加功能
3.1 优雅关闭Spring IOC容器
当我们在Web应用程序中使用Spring IoC容器时,Spring的基于Web的ApplicationContext实现将在关闭应用程序时正常关闭容器,但如果我们在非Web环境中使用它,
例如独立的桌面应用程序,我们我们必须自己向JVM注册一个关闭钩子,以确保Spring IoC容器正常关闭并调用destroy方法释放资源。
在Student类中添加一个destroy()方法:
publicvoid 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>
我们现在将注册一个关闭钩子:
@Testpublicvoid testRegisterShutdownHook(){-
ConfigurableApplicationContext context -
=newClassPathXmlApplicationContext( -
"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=helloyou=youthanks=thank {0}
dialog_zh_CN.properties:
hello=\u4f60\u597dyou=\u4f60thanks=\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获取不同语言的对话框:
@Testpublicvoid testInternationalization(){-
MessageSource resources -
=newClassPathXmlApplicationContext( -
"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",newObject[]{ 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",newObject[]{ chYou },Locale.SIMPLIFIED_CHINESE); assertThat(chHello, equalTo("你好"));assertThat(chThanks, equalTo("谢谢你"));}
4
ApplicationContext引用
有时我们需要在由它管理的bean中获取ApplicationContext的引用,我们可以使用ApplicationContextAware或@Autowired来执行此操作。
让我们看看如何使用ApplicationContextAware:
publicclassCourse{-
privateString name; -
// standard constructors, getters and setters }
我们有一个Teacher类,它根据容器的bean组装它的课程:
publicclassTeacherimplementsApplicationContextAware{-
privateApplicationContext context; -
privateList<Course> courses =newArrayList<>(); -
@Override -
publicvoid setApplicationContext(ApplicationContext applicationContext)throwsBeansException{ -
this.context = applicationContext; -
} -
@PostConstruct -
publicvoid 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>
然后,测试课程属性的注入:
@Testpublicvoid testApplicationContextAware(){-
ApplicationContext context -
=newClassPathXmlApplicationContext( -
"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类更改为:
publicclassTeacher{-
@Autowired -
privateApplicationContext context; -
privateList<Course> courses =newArrayList<>(); -
@PostConstruct -
publicvoid 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的几个方面,包括其基本用法,关闭注册功能,国际化功能以及获取其引用。


