BeanFactory和FactoryBean

  • BeanFactory

 BeanFactory是ioc容器的頂層接口,裏面定義了一些容器基本的功能java

    

 相似ConfigurableBeanFatory和ApplicationContext就是比較高級的容器,除了基本的方法以外,還實現了不少高級的特性,好比支持web,event等,是用來管理和生產bean的工廠方法。web

  • FactoryBean 

  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本身自己

相關文章
相關標籤/搜索