Spring的FactoryBean有以下功能:
通过自定义的Factory类创建自己需要的对象,而不是使用Spring内置的new(或者class.forName)来创建对象。
这样创建的对象有以下好处:
1.和Spring无缝连接,结构清晰
2.可以根据自己的要求创建一些复杂的对象,便于重用。
例如hibernate的SessionFactory就可以是一个FactoryBean,它需要通过配置获得DataSource等信息
3.不用factoryBean行吗?当然可以。比如:org.apache.commons.dbcp.BasicDataSource就是一个普通的JavaBean
使用和不使用factoryBean的区别就是使用简单工厂和new的区别。
4.再扩展一下,如果是抽象工厂,该如何去做呢?
比如有两种不同的SessionFactory,创建一个抽象类AbstractSessionFactoryBean,有两个实现类,创造不同的产品就可以了
以下是一个例子:
先看配置文件:
这段xml表示:myBean是由MyFactoryBean产生的。
很简单的MyBean:
以下是MyFactoryBean:
执行代码,显示:
Hello!
singleton
使用FactoryBean.getObject()创建了MyBean,并且在第一次获得MyBean之前执行了bean.doSomething()方法
singleton方式,spring会自动缓存getObject()获得的对象。
如果isSingleton()方法return false;会有以下结果:
Hello!
Hello!
prototype
表明每次都会执行getObject()方法获得对象
接着说PropertyEditor
PropertyEditor的道理非常简单,传入一个字符串,传出你想要的东西,参考网上的一个例子:
Person对象包含了Address对象,Address包括地址和邮编
传入了 上海淮海路1号,200110,返回一个设置好属性的Address
当你getBean获得Person的时候,已经自动产生了一个address的子对象,并且地址和邮编都已经设置好了
通过自定义的Factory类创建自己需要的对象,而不是使用Spring内置的new(或者class.forName)来创建对象。
这样创建的对象有以下好处:
1.和Spring无缝连接,结构清晰
2.可以根据自己的要求创建一些复杂的对象,便于重用。
例如hibernate的SessionFactory就可以是一个FactoryBean,它需要通过配置获得DataSource等信息
3.不用factoryBean行吗?当然可以。比如:org.apache.commons.dbcp.BasicDataSource就是一个普通的JavaBean
使用和不使用factoryBean的区别就是使用简单工厂和new的区别。
4.再扩展一下,如果是抽象工厂,该如何去做呢?
比如有两种不同的SessionFactory,创建一个抽象类AbstractSessionFactoryBean,有两个实现类,创造不同的产品就可以了
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"/>
以下是一个例子:
先看配置文件:
- <bean id="myBean" class="springStudy.MyFactoryBean"/>
很简单的MyBean:
- package springStudy;
- public class MyBean {
- public void doSomething(){
- System.out.println("Hello!");
- }
- }
- package springStudy;
- import org.springframework.beans.factory.FactoryBean;
- import org.springframework.beans.factory.xml.XmlBeanFactory;
- import org.springframework.core.io.ClassPathResource;
- public class MyFactoryBean implements FactoryBean {
- public static void main(String[] args) {
- XmlBeanFactory factory = new XmlBeanFactory(
- new ClassPathResource("springStudy.spring.xml"));
- MyBean bean1 = (MyBean) factory.getBean("myBean");
- MyBean bean2 = (MyBean) factory.getBean("myBean");
- if(bean1 == bean2){
- System.out.println("singleton");
- }else{
- System.out.println("prototype");
- }
- }
- public Object getObject() throws Exception {
- MyBean bean = new MyBean();
- bean.doSomething();
- return bean;
- }
- public Class getObjectType() {
- return MyBean.class;
- }
- public boolean isSingleton() {
- return true;
- }
- }
Hello!
singleton
使用FactoryBean.getObject()创建了MyBean,并且在第一次获得MyBean之前执行了bean.doSomething()方法
singleton方式,spring会自动缓存getObject()获得的对象。
如果isSingleton()方法return false;会有以下结果:
Hello!
Hello!
prototype
表明每次都会执行getObject()方法获得对象
接着说PropertyEditor
PropertyEditor的道理非常简单,传入一个字符串,传出你想要的东西,参考网上的一个例子:
Person对象包含了Address对象,Address包括地址和邮编
传入了 上海淮海路1号,200110,返回一个设置好属性的Address
- import java.beans.PropertyEditorSupport;
- import java.util.Date;
- import org.springframework.util.StringUtils;
- public class AddressPropertyEditor extends PropertyEditorSupport{
- //支持的格式为 streeValue,doorNumValue,postCode
- public void setAsText(String text) {
- String[] strArr = StringUtils.tokenizeToStringArray(text,",");
- Address add = new Address();
- add.setStreet(strArr[0]);
- add.setZipCode(strArr[2]);
- setValue(add);
- }
- }
- <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
- <property name="customEditors">
- <map>
- <entry key="Address">
- <bean class="AddressPropertyEditor"/>
- </entry>
- </map>
- </property>
- </bean>
- <bean id="person" class="Person">
- <property name="name" value="Kent"/>
- <property name="address" value="上海淮海路1号,200110"/>
- </bean>