spring学习笔记:ioc容器高级特性

Spring容器的高级特性涉及到属性编辑使用外部属性文件国际化容器事件等等; 今天讲解一下属性编辑器,使用外部资源,国际化。


属性编辑器  如果你没有了解过属性编辑器,建议你先google一下,我简单的解释一下什么是属性编辑器,看一个新写的有代表性的bean
package model; import java.io.File; import java.net.URL; import java.util.List; public class BasicProperties { private int age; private float weight; private File file; private List books; private URL url; public URL getUrl() { return url; } public void setUrl(URL url) { this.url = url; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List getBooks() { return books; } public void setBooks(List books) { this.books = books; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public float getWeight() { return weight; } public void setWeight(float weight) { this.weight = weight; } }

配置文件:
<bean id="basicPropertiesTest" class="model.BasicProperties"> <property name="age" value="27" /> <property name="weight" value="61.5" /> <property name="file" value="c://1.txt" /> <property name="books"> <list> <ref bean="myBook1" /> <ref bean="myBook2" /> <ref bean="myBook3" /> </list> </property> <property name="url" value="http://www.google.com" /> </bean>

配置中的value都是字符串的形式出现的,但是我们的BasicProperties的属性不都是字符串,那么把字符串这种字面量转换为bean的属性对应的类型靠的就是属性编辑器。比如上面 spring能够自动把c://1.txt识别为File的,把http://www.google.com自动转化为URL. Spring为基本数据类型包括包装类型, 集合类( List,Set,Map,Collection ), 资源类( File, Class, Locale, Resource, InoutStream, URL )提供了默认的编辑器,如果我们想实现自己的属性编辑器,比如能够把05/08/2009自动识别为日期类型,我们需要做以下的工作:
1 写一个Editor继承自PropertyEditorSupport,
package model.propertyeditor; import java.beans.PropertyEditorSupport; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DateEditor extends PropertyEditorSupport{ //该方法要覆写 public void setAsText(String text){ SimpleDateFormat format = new SimpleDateFormat("mm/dd/yyyy"); Date date = null; try { date = format.parse(text); } catch (ParseException e) { e.printStackTrace(); } setValue(date); } }

2 在IOC容器中注册这个编辑器.说注册有点玄乎,其实就是让容器知道这个编辑器的存在, 也就是配置一下.

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="java.util.Date"> <bean class="model.propertyeditor.DateEditor" /> </entry> </map> </property> </bean>

3 写一个带有日期类的class测试一下:
package test; import java.util.Date; public class Foo { private Date date; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }

4 配置一个Foo Bean,
<bean id="foo" class="test.Foo"> <property name="date" value="05/05/2008" /> </bean>
写一个测试类看容器是否真的可以把05/05/2008转换为Date:
public class Test { public static void main(String[] args) throws InterruptedException{ ApplicationContext c = new ClassPathXmlApplicationContext("spring-test.xml"); Foo foo = (Foo)c.getBean("foo"); System.out.println(foo.getDate().toLocaleString()); }}打印出Jan 5, 2008 12:05:00 AM, 成功!


使用外部属性文件  为什么要使用外部熟性文件? 举例子:我们经常把数据库链接,用户名,密码单独放在一个properties文件中,但是我们希望在bean config文件中可以使用它,那就以这个例子来做以下,我们的db.properties文件如下:
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc.url=jdbc:microsoft:sqlserver://localhost:2431 jdbc.username=sa jdbc.password=123456
该文件放在classpath下面根目录上.我们需要把这个属性文件也注册到IOC容器:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:db.properties</value> </list> </property> </bean>

配置一个DateSource,并且使用这个属性文件:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>

然后启动容器,没报错,说明配置成功.这个dataSource在讲spring jdbc的时候会用到.
国际化  国际化也就是我们的程序能支持多语言环境, 程序中的提示信息是多语言的.假如我们有这样的资源文件:
msg._en_US.properties,内容如下:
greeting.morning=Good morning
greeting.afternoon=Good afternoon

还有一个中文版本的:msg.properties
greeting.morning=早上好
greeting.afternoon=下午好

但是资源文件只能包含ascii字符,幸好java提供了一个把unicode字符转换为ascii的工具native2ascii,在jdk/bin下面.调用该命令把资源文件转化一下:
native2ascii c:/msg.properties c:/msg_zh_CN.properties. 把生成的文件msg_zh_CN.properties拷贝到src根目录.注意文件的命名: 文件名_语言简称_国家简称.properties ;  生成的msg_zh_CN.properties如下:
greeting.morning=/u65E9/u4E0A/u597D
greeting.afternoon=/u4E0B/u5348/u597D

配置一个messageResource:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>msg</value> </list> </property> </bean>
注意路径,如果资源文件放在某个包下面,则要带上包名 pkgname/pkgname/msg;
测试程序:
public class Test { public static void main(String[] args) throws InterruptedException{ ApplicationContext c = new ClassPathXmlApplicationContext("spring-test.xml"); String msg1 = c.getMessage("greeting.morning", null,Locale.CHINA); String msg2 = c.getMessage("greeting.morning", null,Locale.US); System.out.println(msg1); System.out.println(msg2); }}
消息文件中可以有占位符,context.getMessage()的第二个参数是数组, 可以放到占位符上.比如消息:
greeting.morning=good morning {0}, today is {1} ,则:
String msg = c.getMessage("greeting.morning",new Object[]{"John", new GregorianCalendar().getTime

()},Locale.US);

 

下一讲将学习spring aop.

你可能感兴趣的:(spring,bean,Date,IOC,Class,books)