BeanFactory是ioc容器的頂層接口,裏面定義了一些容器基本的功能java
相似ConfigurableBeanFatory和ApplicationContext就是比較高級的容器,除了基本的方法以外,還實現了不少高級的特性,好比支持web,event等,是用來管理和生產bean的工廠方法。web
FactoryBean以bean結尾,自己是一個bean,可是一個具備修飾以及生產bean功能的工廠Bean,參考以下:spring
1)新建一個對象personide
public class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
2) 增長一個註解配置類(和bean.xml相似)測試
package com.sendo.spring.config; import com.sendo.spring.FactoryBean.PersonFactoryBean; import com.sendo.spring.bean.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by ysf on 2018/10/16. */ @Configuration public class BeanConfig { @Bean("person") public Person person() { return new Person("sendo", 20); } }
3) 運行,查看bean的內容 this
/** * Created by ysf on 2018/10/16. */ public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); Person person = (Person) context.getBean("person"); System.out.println(person); } }
4) 運行結果:spa
能夠看到,這個bean就是咱們在BeanConfig裏面配置的信息。下面改成用FactoryBean來建立bean:3d
5) 新建一個PersonFactoryBeancode
public class PersonFactoryBean implements FactoryBean<Person> { private String name; public PersonFactoryBean(String name) { this.name = name; } @Override public Person getObject() throws Exception { return new Person(name, 20); } @Override public Class<?> getObjectType() { return Person.class; } @Override public boolean isSingleton() { return false; } @Override public String toString() { return "PersonFactoryBean{" + "name='" + name + '\'' + '}'; } }
須要繼承FactoryBean接口,並覆蓋getObject()、getObjectType()、isSingleton()方法。xml
而後修改BeanConfig, 增長建立person的工廠bean
/** * Created by ysf on 2018/10/16. */ @Configuration public class BeanConfig { @Bean("person") public Person person() { return new Person("sendo", 20); } @Bean("personFactoryBean") public PersonFactoryBean personFactoryBean() { return new PersonFactoryBean("cat"); } }
從新運行,查看獲取personFactoryBean的bean是什麼
public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); Person person = (Person) context.getBean("personFactoryBean"); System.out.println(person); } }
能夠看到,拿到的bean是PersonFactoryBean裏面的getObject()方法返回的結果,下面看下BeanFactory有一段這麼描述:
就是若是獲取bean時,加上前綴&,則拿到的bean是這個工廠bean自己,而不是工廠bean方法裏getObject()返回的結果,測試以下:
public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); // 這裏在原有的personFactoryBean前面加上& Person person = (Person) context.getBean("&personFactoryBean"); System.out.println(person); } }
能夠看到獲取到的對象是PersonFactoryBean, 因爲沒法轉換成Person,才所以報錯,重寫修改類型
public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); // 這裏在原有的personFactoryBean前面加上& PersonFactoryBean person = (PersonFactoryBean) context.getBean("&personFactoryBean"); System.out.println(person); } }
獲取到了PersonFactoryBean本身自己