BeanFactory and FactoryBean

Keywords: Java Spring xml

  • BeanFactory

BeanFactory is the top-level interface of the ioc container, which defines some basic functions of the container

    

Configurable bean Fatory and Application Context are more advanced containers. In addition to the basic methods, they also implement many advanced features, such as supporting web,event, etc., which are factory methods used to manage and produce beans.

  • FactoryBean 

FactoryBean ends with a bean and is itself a bean, but a factory bean that has the ability to modify and produce beans can be referred to as follows:

1) Create a new object person

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) Add an annotation configuration class (similar to 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) Run and view the contents of the bean.

/**
 * 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) Operation results:

As you can see, this bean is the information we configure in BeanConfig. Instead, use FactoryBean to create beans:

5) Create a new PersonFactoryBean

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 + '\'' +
                '}';
    }
}

You need to inherit the FactoryBean interface and override the getObject(), getObjectType(), and isSingleton() methods.

Then modify BeanConfig to add the factory bean that created person

/**
 * 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");
    }
}

Rerun to see what the bean that gets the personFactoryBean is

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);
    }
}

As you can see, the bean you get is the result of the getObject() method returned from PersonFactoryBean. Here's a description of BeanFactory:

If the prefix & is added when the bean is retrieved, the resulting bean is the factory bean itself, not the result returned by getObject() in the factory bean method. The test is as follows:

public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        // Here, before the original personFactoryBean, add&
        Person person = (Person) context.getBean("&personFactoryBean");
        System.out.println(person);
    }
}

You can see that the object you get is PersonFactoryBean, which can't be converted to Person, so you can report an error and override the modification type.

public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        // Here, before the original personFactoryBean, add&
        PersonFactoryBean person = (PersonFactoryBean) context.getBean("&personFactoryBean");
        System.out.println(person);
    }
}

Get the PersonFactoryBean itself

Posted by djot on Thu, 31 Jan 2019 21:09:16 -0800