Spring中的FactoryBean

1.概述

Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean,这两种Bean都被容器管理,但工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。在Spring框架内部,有很多地方有FactoryBean的实现类,它们在很多应用如(Spring的AOP、ORM、事务管理)及与其它第三框架(ehCache)集成时都有体现,下面简单分析FactoryBean的用法。

2.实例

以下SimpleFactoryBean类实现了FactoryBean接口中的三个方法。并将该类配置在XML中。

public class SimpleFactoryBean implements FactoryBean {  
            private boolean flag;  
          
            public Object getObject() throws Exception {  
                if (flag) {  
                    return new Date();  
                }  
                return new String("false");  
            }  
          
            @SuppressWarnings("unchecked")  
            public Class getObjectType() {  
                return flag ? Date.class : String.class;  
            }  
          
            public boolean isSingleton() {  
                return false;  
            }  
          
            public void setFlag(boolean flag) {  
                this.flag = flag;  
            }  
        }  
          
        <bean id="factoryBeanOne" class="com.study.demo.factorybean.SimpleFactoryBean" >  
            <property name="flag">  
                <value>true</value>  
            </property>  
        </bean>  
          
        <bean id="factoryBeanTwo" class="com.study.demo.factorybean.SimpleFactoryBean" >  
            <property name="flag">  
                <value>false</value>  
            </property>  
        </bean>  
          
        public class MainTest {  
            public static void main(String[] args) {  
                Resource res = new ClassPathResource("bean.xml");  
                BeanFactory factory = new XmlBeanFactory(res);  
                System.out.println(factory.getBean("factoryBeanOne").getClass());  
                System.out.println(factory.getBean("factoryBeanTwo").getClass());  
            }  
        }

通过简单的测试可知,该类输出如下:

classjava.util.Date

classjava.lang.String

也就是说,容器通过getBean方法返回的不是FactoryBean本身,而是FactoryBean实现类中getObject()方法所返回的对象

3.FactoryBean的扩展应用

以Spring集成ehcache为例,看下org.springframework.cache.ehcache.EhCacheManagerFactoryBean类与org.springframework.cache.ehcache.EhCacheFactoryBean类。EhCacheManagerFactoryBean类中的getObject()和getObjectType()方法返回的如下:

public Object getObject() {  
                return this.cacheManager;  
            }  
          
        public Class getObjectType() {  
                return (this.cacheManager != null ? this.cacheManager.getClass() : CacheManager.class);  
            }

EhCacheFactoryBean类中的getObject()和getObjectType()方法返回的如下:

public Object getObject() {  
                return this.cache;  
            }  
          
            public Class getObjectType() {  
                return (this.cache != null ? this.cache.getClass() : Ehcache.class);  
            }

有了这两个FactoryBean,在Spring容器中使用ehcache就变得很简单了。配置如下:

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    
                  <property name="configLocation">    
                  <value>classpath:ehcache.xml</value>    
                  </property>    
            </bean>    
          
            <bean id="levelOneCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">    
                  <property name="cacheManager">    
                        <ref local="cacheManager" />    
                  </property>    
                  <property name="cacheName">    
                        <value>levelOneCache</value>    
                  </property>    
            </bean>

应用代码如下:

public class MainTest {  
            public static void main(String[] args) {  
                Resource res = new ClassPathResource("bean.xml");  
                BeanFactory factory = new XmlBeanFactory(res);  
                //取到CacheManager类的实例   
                CacheManager cacheManager = (CacheManager) factory  
                        .getBean("cacheManager");  
                //取到Cache类的实例   
                Cache levelOneCache = cacheManager.getCache("levelOneCache");  
            }  
        }

相关推荐