Spring 中區分「普通 Bean」與「FactoryBean」。FactoryBean 的 getObject() 回傳值才是真正注入容器的物件,廣泛應用於 AOP Proxy、Transaction Proxy 等核心模組。本文透過範例示範動態回傳不同型別、取得 FactoryBean 本身實例的特殊語法 &beanName。
<!-- 普通 Bean:直接回傳 String 實例 -->
<bean name="bean1" class="java.lang.String">
<constructor-arg value="我是字串!"/>
</bean>
public class FactoryBeanDemo implements FactoryBean {
private String name;
public void setName(String name) { this.name = name; }
public Object getObject() throws Exception {
return "date".equals(name) ? new Date() : new String("這是一個字串!");
}
public Class getObjectType() {
return "date".equals(name) ? Date.class : String.class;
}
public boolean isSingleton() { return false; }
}
<bean name="myFactoryBean" class="pkg.FactoryBeanDemo"/>
<bean name="myFactoryBean1" class="pkg.FactoryBeanDemo">
<property name="name" value="date"/>
</bean>
BeanFactory factory = new XmlBeanFactory(res);
System.out.println(factory.getBean("myFactoryBean").getClass()); // class java.lang.String
System.out.println(factory.getBean("myFactoryBean1").getClass()); // class java.util.Date
在 bean 名稱前加 & 即可取得 FactoryBean 實例而非其產出的物件:
System.out.println(factory.getBean("&myFactoryBean").getClass()); // class pkg.FactoryBeanDemo
System.out.println(factory.getBean("&myFactoryBean1").getClass()); // class pkg.FactoryBeanDemo
getObject() 根據租戶上下文回傳對應 DataSource。getObject() 才建立連線池、線程池等昂貴資源。