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

相关文章
相关标签/搜索