首先是BeanFactory和FactoryBean的區別:
- FactoryBean:是一個Java Bean,但是它是一個能生產對象的工廠Bean,它的實現和工廠模式及修飾器模式很像。比如下:我們把bean比作豬,那么FactoryBean可以算是一個母豬,首先它本身也是一只豬,但它能夠下小豬。
- BeanFactory:這就是一個Factory,是一個IOC容器或者叫對象工廠,它里面存著很多的bean。還用上面那個比如:如果bean是豬,那么它可以理解成豬圈,豬圈里面有很
FactoryBean的核心就在于通過getObject方法可以獲取的是它所生產的對象
實現FactoryBean 必須實現接口的3個方法:getObject、getObjectType、isSingleton
使用FactoryBean的場景有兩個:1、創建代理對象 2、通過xml配置方式比較繁瑣或有難度,那么可以通過FactoryBean 在java代碼里面配置bean
網上找了兩個例子,說明這兩點
1.創建代理對象的例子:
ZFFactoryBean
1 package com.spring.factorybean; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 import org.springframework.beans.factory.DisposableBean; 8 import org.springframework.beans.factory.FactoryBean; 9 import org.springframework.beans.factory.InitializingBean; 10 11 public class ZFFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean { 12 13 // 被代理對象實現的接口名(在使用Proxy時需要用到,用于決定生成的代理對象類型) 14 private String interfaceName; 15 16 // 被代理的對象 17 private Object target; 18 19 // 生成的代理對象 20 private Object proxyObj; 21 22 public void destroy() throws Exception { 23 System.out.println("distory..."); 24 } 25 26 public void afterPropertiesSet() throws Exception { 27 28 proxyObj = Proxy.newProxyInstance(this.getClass().getClassLoader(), 29 new Class[] { Class.forName(interfaceName) }, new InvocationHandler() { 30 31 public Object invoke(Object proxy, Method method, Object[] args) 32 throws Throwable { 33 System.out.println("method:" + method.getName()); 34 System.out.println("Method before..."); 35 Object result = method.invoke(target, args); 36 System.out.println("Method after..."); 37 return result; 38 } 39 }); 40 41 System.out.println("afterPropertiesSet"); 42 } 43 44 public Object getObject() throws Exception { 45 System.out.println("getObject"); 46 return proxyObj; 47 } 48 49 public Class<?> getObjectType() { 50 return proxyObj == null ? Object.class : proxyObj.getClass(); 51 } 52 53 public boolean isSingleton() { 54 return true; 55 } 56 57 public String getInterfaceName() { 58 return interfaceName; 59 } 60 61 public void setInterfaceName(String interfaceName) { 62 this.interfaceName = interfaceName; 63 } 64 65 public Object getTarget() { 66 return target; 67 } 68 69 public void setTarget(Object target) { 70 this.target = target; 71 } 72 73 }
PersonService 和 PersonServiceImpl的代碼此處省略
xml配置:
1 <bean id="personService" class="com.spring.service.impl.PersonServiceImpl" scope="prototype"> 2 <property name="name" value="is_zhoufeng" /> 3 </bean> 4 5 <bean id="zfPersonService" class="com.spring.factorybean.ZFFactoryBean"> 6 <property name="interfaceName" value="com.spring.service.PersonService" /> 7 <property name="target" ref="personService"/> 8 </bean>
用法:
1 @Test 2 public void test06() { 3 PersonService ps = context.getBean("zfPersonService", PersonService.class); 4 5 ps.sayHello(); 6 7 String name = ps.getName(); 8 9 System.out.println(name); 10 }
2.配置較為復雜的bean
Person類,get set省略
1 public class Person { 2 private String name; 3 private String address; 4 private int age; 5 }
如果用xml配置,如下,會比較麻煩:
1 <bean id="personBean" class="com.gh.MavenTest.Person"> 2 <property name="name" value="gh1" /> 3 <property name="address" value="address1" /> 4 <property name="age" value="28" /> 5 </bean>
換成FactoryBean的方式配置:
1 public class PersonFactoryBean implements FactoryBean<Person>{ 2 3 private String personInfo; 4 5 public Person getObject() throws Exception { 6 Person person = new Person () ; 7 String [] infos = personInfo.split ( "," ) ; 8 person.setName(infos[0]); 9 person.setAddress(infos[1]); 10 person.setAge(Integer.parseInt(infos[2])); 11 return person; 12 } 13 14 public Class<Person> getObjectType() { 15 return Person.class; 16 } 17 18 public boolean isSingleton() { 19 return true; 20 } 21 }
xml再配置一下:
1 <bean id="personFactory" class="com.hik.MavenTest.PersonFactory"> 2 <property name="personInfo" value="gh2,address2,22"></property> 3 </bean>
那么這個時候我們getBean("personFactory")得到的就是Person對象而不是PersonFactoryBean對象
如果要取到PersonFactoryBean這個bean, 在beanName前面加上&,即getBean("&personFactory")
spring自帶了不少FactoryBean的實現,最下面是我們所在的公司的實現

具體使用的時候,還可以用FactoryBean創建多個bean
1 <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" /> 2 <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" /> 3 <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" /> 4 <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" /> 5 <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
浙公網安備 33010602011771號