FactoryBean有什麼做用:spring
FactoryBean是以工廠形式生成Bean,在對Bean進行修飾以後返回Bean。app
經常使用的使用場景爲: 根據不一樣的配置類型返回不一樣類型的處理Bean,總體上簡化了XML配置等。ide
Spring自己有70多個FactoryBean的實現,經過它隱藏了一些複雜的實現細節。測試
舉個例子,看看經過FactoryBean簡化XML配置。ui
public class Student { /** 姓名 */ private String name; /** 年齡 */ private int age; /** 班級名稱 */ private String className; }
實現FactoryBeen接口:this
public class StudentFactoryBean implements FactoryBean<Student> { private String studentInfo; @Override public Student getObject() throws Exception { if (this.studentInfo == null) { throw new IllegalArgumentException("'studentInfo' is required"); } String[] splitStudentInfo = studentInfo.split(","); if (null == splitStudentInfo || splitStudentInfo.length != 3) { throw new IllegalArgumentException("'studentInfo' config error"); } Student student = new Student(); student.setName(splitStudentInfo[0]); student.setAge(Integer.valueOf(splitStudentInfo[1])); student.setClassName(splitStudentInfo[2]); return student; } @Override public Class<?> getObjectType() { return Student.class; } public void setStudentInfo(String studentInfo) { this.studentInfo = studentInfo; } }
建立XML配置:code
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--注意:class不是Student而是StudentFactoryBean--> <bean id="student" class="com.lyc.cn.day03.StudentFactoryBean" p:studentInfo="張三,25,三年二班"/> </beans>
測試:xml
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("day03.xml"); System.out.println(applicationContext.getBean("student")); System.out.println(applicationContext.getBean("&student")); Student{name='張三', age=25, className='三年二班'} org.springframework.beans.factory_bean.StudentFactoryBean@1ae369b7
這樣就簡化了經過BeanFactory接口簡化配置XML的做業了。若是不加&
返回的是實例,加了返回的是工廠bean自己。接口
默認返回單例:get
//實例是否單例模式,默認返回true default boolean isSingleton() { return true; }
經過FactoryBean個性化輸出Bean。
public interface Animal { void sayHello(); } public class Cat implements Animal { @Override public void sayHello() { System.out.println("hello, 喵喵喵..."); } } public class Dog implements Animal { @Override public void sayHello() { System.out.println("hello, 汪汪汪..."); } }
對於Animal 接口有兩個實現:Cat和Dog。
新建AnimalFactorybean:
public class AnimalFactoryBean implements FactoryBean<Animal> { private String animal; @Override public Animal getObject() throws Exception { if (null == animal) { throw new IllegalArgumentException("'animal' is required"); } if ("cat".equals(animal)) { return new Cat(); } else if ("dog".equals(animal)) { return new Dog(); } else { throw new IllegalArgumentException("animal type error"); } } @Override public Class<?> getObjectType() { if (null == animal) { throw new IllegalArgumentException("'animal' is required"); } if ("cat".equals(animal)) { return Cat.class; } else if ("dog".equals(animal)) { return Dog.class; } else { throw new IllegalArgumentException("animal type error"); } } public void setAnimal(String animal) { this.animal = animal; } }
增長XML配置:
<bean id="animal" class="com.lyc.cn.day03.AnimalFactoryBean" p:animal="cat"/>
測試:
public void testAnimalFactoryBean() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("day03.xml"); Animal animal = applicationContext.getBean("animal", Animal.class); animal.sayHello(); } --------------------- hello, 喵喵喵...