BeanFactory 和 FactoryBean

1 Introduction

BeanFactory and FactoryBean can be said to be two unrelated things, but they are inextricably related. Literally, a bean factory and a factory bean describe the difference between them in one sentence: BeanFactory is a factory class used to manage all beans, FactoryBean is a bean that produces a certain type of bean, and it is also a bean in itself.

2. In-depth understanding

What are the ways to create beans that we know?

  • Use Spring XML configuration. This method is used in pure Spring applications and is suitable for simple small applications. When the application becomes complex, it will cause the expansion of the XMl configuration file, which is not conducive to object management.
<bean id="xxxx"  class="xxxx.xxxx"/>
  • Use @Component, @Service, @Controler, @Repository annotation
  • Use @Bean annotation
  • Using the annotation @Import, the object will also be created and injected into the container
  • Use ImportSelector or ImportBeanDefinitionRegistrar interface, with @Import implementation
  • Manually inject the Bean container. In some scenarios, dynamic code injection is required. The above methods are not applicable.

In the XML mode, there are several types, through the construction method, setter method, and through the factory class to create beans. The way of the factory class is related to what we said in this article FactoryBean.

We divide beans into two types, one is ordinary beans and the other is factory beans. The reason for this classification, you can understand that the creation of ordinary beans is relatively simple and can be configured in XML, but factory beans are more complicated and need to use a lot of initialization parameters, etc. At this time, it is very complicated to configure in XML. , So we can create this complex object through the factory bean.

Having said that, I believe you already understand the difference between the two.

3. Continue to learn more

3.1 BeanFactory

This is actually the container root interface of all Spring Beans. It defines a set of specifications for the Spring container and provides a complete set of specifications for the IOC container, such as the getBean method we commonly use.

Definition method:

  • getBean(String name): The method to get the corresponding Bean object in the Spring container, if it exists, return the object
  • containsBean(String name): Does the object exist in the Spring container
  • isSingleton(String name): whether beanName is a singleton object
  • isPrototype(String name): Determine whether the bean object is a multi-case object
  • isTypeMatch(String name, ResolvableType typeToMatch): Determine whether the bean obtained by the name value matches typeToMath
  • getType(String name): Get the Bean's Class type
  • getAliases(String name): Get all the aliases corresponding to name

The main implementation classes (including abstract classes):

  • AbstractBeanFactory: Abstract Bean Factory, most of the implementation classes are inherited from him
  • DefaultListableBeanFactory: Spring's default factory class
  • XmlBeanFactory: Bean factory used when XML configuration was used in the early stage
  • AbstractXmlApplicationContext: Abstract application container context object
  • ClassPathXmlApplicationContext: XML parsing context object, user creates Bean object, we used it when we wrote Spring earlier

How to use:

  1. Use ClassPathXmlApplicationContext to read the corresponding xml file instance corresponding context object
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
    
    "applicationContext.xml"});
BeanFactory factory = (BeanFactory) context;

3.2 FactoryBean

This class is a form of SpringIOC container creation of Bean. Bean created in this way will have an additive method, which combines a simple factory design pattern with a decorator pattern.
Some people will ask, I directly use the Spring default method to create Bean is not fragrant, why do you still need to use FactoryBean to do, in some cases, when the instance Bean object is more complicated, it will be more complicated to create the bean in the traditional way, for example (using xml configuration), this will happen The FactoryBean interface allows users to customize the instantiation process of the Bean interface by implementing the interface. That is, one layer is packaged, and the complicated initialization process is packaged so that the caller does not need to concern the specific implementation details.

method:

  • T getObject(): return instance
  • Class<?> getObjectType();: Returns the type of the bean of the decoration object
  • default boolean isSingleton(): Whether the Bean is a singleton

Commonly used classes:

  • ProxyFactoryBean: Aop proxy bean
  • GsonFactoryBean: Gson

use:

  1. Spring XML way

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="demo" class="cn.lonecloud.spring.example.bo.Person">
        <property name="age" value="10"/>
        <property name="name" value="xiaoMing"/>
    </bean>

    <bean id="demoFromFactory" class="cn.lonecloud.spring.example.bean.PersonFactoryBean">
        <property name="initStr" value="10,init from factory"/>
    </bean>
</beans>

personFactoryBean.java

public class PersonFactoryBean implements FactoryBean<Person> {
    
    

    /**
     * 初始化Str
     */
    private String initStr;

    @Override
    public Person getObject() throws Exception {
    
    
        //这里我需要获取对应参数
        Objects.requireNonNull(initStr);
        String[] split = initStr.split(",");
        Person p=new Person();
        p.setAge(Integer.parseInt(split[0]));
        p.setName(split[1]);
        //这里可能需要还要有其他复杂事情需要处理
        return p;
    }

    @Override
    public Class<?> getObjectType() {
    
    
        return Person.class;
    }

    public String getInitStr() {
    
    
        return initStr;
    }

    public void setInitStr(String initStr) {
    
    
        this.initStr = initStr;
    }
}

main method

public class SpringBeanFactoryMain {
    
    

    public static void main(String[] args) {
    
    
        //这个是BeanFactory
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("application.xml");
        //获取对应的对象化
        Object demo = beanFactory.getBean("demo");
        System.out.println(demo instanceof Person);
        System.out.println(demo);
        //获取从工厂Bean中获取对象
        Person demoFromFactory = beanFactory.getBean("demoFromFactory", Person.class);
        System.out.println(demoFromFactory);
        //获取对应的personFactory
        Object bean = beanFactory.getBean("&demoFromFactory");
        System.out.println(bean instanceof PersonFactoryBean);
        PersonFactoryBean factoryBean=(PersonFactoryBean) bean;
        System.out.println("初始化参数为:"+factoryBean.getInitStr());
    }
}

Output

true
Person{name='xiaoMing', age=10}
Person{name='init from factory', age=10}
true
initialization parameters are: 10,init from factory

the difference

  1. BeanFactory: a factory interface responsible for producing and managing Beans, providing a Spring Ioc container specification,
  2. FactoryBean: A way of Bean creation, an extension of Bean. For complex Bean object initialization and creation, use the creation details of its encapsulable object.

Guess you like

Origin blog.csdn.net/saienenen/article/details/112724089