public interface BeanFactory { //標註是獲取FactoryBean的實現類,而不是調用getObject()獲取的實例 String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
從源碼的方法定義上,就能夠看出,BeanFactory
做爲bean的容器管理器,提供了一系列獲取bean以及獲取bean屬性的方法。java
寫一個小例子試驗下:spring
SimpleBean:安全
public class SimpleBean { public void send() { System.out.println("Hello Spring Bean!"); } }
Spring配置文件config.xml:ide
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="simpleBean" class="base.SimpleBeanFactoryBean"/> </beans>
測試方法:測試
public static void main(String[] args) throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); BeanFactory beanFactory = context.getAutowireCapableBeanFactory(); System.out.println("經過名稱獲取bean"); SimpleBean simpleBean = (SimpleBean) beanFactory.getBean("simpleBean"); simpleBean.send(); System.out.println("經過名稱和類型獲取bean"); simpleBean = beanFactory.getBean("simpleBean", SimpleBean.class); simpleBean.send(); System.out.println("經過類型獲取bean"); simpleBean = beanFactory.getBean(SimpleBean.class); simpleBean.send(); boolean containsBean = beanFactory.containsBean("simpleBean"); System.out.println("是否包含 simpleBean ? " + containsBean); boolean singleton = beanFactory.isSingleton("simpleBean"); System.out.println("是不是單例? " + singleton); boolean match = beanFactory.isTypeMatch("simpleBean", ResolvableType.forClass(SimpleBean.class)); System.out.println("是不是SimpleBean類型 ? " + match); match = beanFactory.isTypeMatch("simpleBean", SimpleBean.class); System.out.println("是不是SimpleBean類型 ? " + match); Class<?> aClass = beanFactory.getType("simpleBean"); System.out.println("simpleBean 的類型是 " + aClass.getName()); String[] aliases = beanFactory.getAliases("simpleBean"); System.out.println("simpleBean 的別名 : " + Arrays.toString(aliases)); }
控制檯結果:ui
經過名稱獲取bean Hello Spring Bean! 經過名稱和類型獲取bean Hello Spring Bean! 經過類型獲取bean Hello Spring Bean! 是否包含 simpleBean ? true 是不是單例? true 是不是SimpleBean類型 ? true 是不是SimpleBean類型 ? true simpleBean 的類型是 base.SimpleBean simpleBean 的別名 : []
public interface FactoryBean<T> { /** * 獲取一個bean,若是配置了工廠bean,在getBean的時候,將會調用此方法,獲取一個bean */ T getObject() throws Exception; /** * 獲取bean的類型 */ Class<?> getObjectType(); /** * 是不是單例 */ boolean isSingleton(); }
接口是泛型,定義了三個方法,其中getObject()
是工廠模式的體現,將會經過此方法返回一個bean的實例。線程
一個小例子:code
public class SimpleBeanFactoryBean implements FactoryBean<SimpleBean> { @Override public SimpleBean getObject() throws Exception { System.out.println("MyFactoryBean getObject"); return new SimpleBean(); } @Override public Class<?> getObjectType() { System.out.println("MyFactoryBean getObjectType"); return SimpleBean.class; } @Override public boolean isSingleton() { return false; } }
以上能夠修改成單例模式,能夠作成線程安全的單例,可塑性較高。xml
配置文件config.xml:對象
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="simple" class="base.SimpleBeanFactoryBean"/> </beans>
注意,咱們在這裏只配置了SimpleBeanFactoryBean
,並無配置SimpleBean
,接下來看下getBean
方法的輸出。
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); SimpleBean simpleBean = context.getBean(SimpleBean.class); simpleBean.send();
控制檯輸出:
MyFactoryBean getObjectType MyFactoryBean getObject Hello Spring Bean!
由此咱們能夠看出FactoryBean
的執行流程
getObjectType
獲取bean的類型getObject
方法獲取bean的實例BeanFactory
和FactoryBean
其實沒有關係,只是名稱比較像而已。
BeanFactory
是IOC最基本的容器,負責生產和管理bean,它爲其餘具體的IOC容器提供了最基本的規範。FactoryBean
是一個接口,當在IOC容器中的Bean實現了FactoryBean
後,經過getBean(String BeanName)
獲取到的Bean對象並非FactoryBean
的實現類對象,而是這個實現類中的getObject()
方法返回的對象。要想獲取FactoryBean
的實現類,就要getBean(&BeanName)
,在BeanName
以前加上&。