原文地址:http://blog.csdn.net/joenqc/article/details/66479154java
首先,這倆都是個接口…spring
實現 BeanFactory
接口的類代表此類事一個工廠,做用就是配置、新建、管理 各類Bean。app
而 實現 FactoryBean
的類代表此類也是一個Bean,類型爲工廠Bean(Spring中共有兩種bean,一種爲普通bean,另外一種則爲工廠bean)。顧名思義,它也是用來管理Bean的,而它自己由spring管理。ui
一個Bean想要實現 FactoryBean
,必須實現如下三個接口:spa
1. Object getObject():返回由FactoryBean建立的Bean的實例 2. boolean isSingleton():肯定由FactoryBean建立的Bean的做用域是singleton仍是prototype; 3. getObjectType():返回FactoryBean建立的Bean的類型。
有一點須要注意,若是將一個實現了FactoryBean的類成功配置到了spring上下文中,那麼經過該類對象的名稱(好比appleFactoryBean)從spring的applicationContext或者beanFactory獲取bean時,獲取到的是appleFactoryBean建立的apple實例,而不是appleFactoryBean本身,若是想經過spring拿到appleFactoryBean,須要在名稱前加 &
符號 :.net
out.println(applicationContext.getBean("&appleFactoryBean"))
這個prefix在BeanFactory接口源碼中有提到:prototype
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&";
還有一點須要注意,FactoryBean管理的bean實際上也是由spring進行配置、實例化、管理,所以由FactoryBean管理的bean不能再次配置到spring配置文件中(xml、java類配置、註解均不能夠),不然會報以下異常:code
Exception in thread "main" org.springframework.beans.factory.BeanIsNotAFactoryException: Bean named 'appleFactoryBean' is expected to be of type 'org.springframework.beans.factory.FactoryBean' but was actually of type 'java.lang.Object' at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1612) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:317) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84) at com.joen.testspringcontainer.Start.main(Start.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
附上一個例子:server
spring配置類:xml
@Configuration @ComponentScan public class Configurations { }
AppleBean :
//@Component 這裏不能夠加註解 !!!!!! public class AppleBean{ }
AppleFactoryBean :
@Component public class AppleFactoryBean implements FactoryBean{ public Object getObject() throws Exception { return new AppleBean(); } public Class<?> getObjectType() { return AppleBean.class; } public boolean isSingleton() { return false; } }
啓動類 :
public class Start { public static void main(String[] args){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Configurations.class); out.println(applicationContext.getBean("appleFactoryBean"));//獲得的是apple out.println(applicationContext.getBean("&appleFactoryBean"));//獲得的是apple工廠 } }