Today I’m going to introduce you to the @FactoryBean annotation.

1. Introduction to @FactoryBean annotations

A FactoryBean is a Bean that implements the FactoryBean interface. The Bean ID obtained from BeanFactory is actually the instance object returned by getObject() in FactoryBean, not the FactoryBean itself. To get the FactoryBean object itself, you get it by prefacing the ID with an ampersand.

BeanFactory section code:

Description: String FACTORY_BEAN_PREFIX = “&”, the ampersand symbol means to get the FactoryBean itself

package org.springframework.beans.factory; import org.springframework.beans.BeansException; import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; }Copy the code

The @factoryBean source code is as follows:

After Spring3.0, factorybeans began to support generics, meaning that the interface declaration was changed to the form of factorybeans

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}
Copy the code

There are three ways to implement the FactoryBean interface

  • GetObject: Gets the corresponding instance object of the bean

  • GetObjectType: Gets the instance type that a factoryBean gets

  • IsSingleton: Whether the instance created by the factoryBean is a single instance

3. Usage examples

3.1 the new Book. Java

package com.spring.bean; public class Book { private String bookName; private String bookType; private double price; public Book(String bookName, String bookType, double price) { this.bookName = bookName; this.bookType = bookType; this.price = price; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getBookType() { return bookType; } public void setBookType(String bookType) { this.bookType = bookType; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Book{" + "bookName='" + bookName + '\'' + ", bookType='" + bookType + '\'' + ", price=" + price + '}'; }}Copy the code

3.2 new BookFactoryBean. Java

package com.spring.bean; import org.springframework.beans.factory.FactoryBean; public class BookFactoryBean implements FactoryBean<Book> { public BookFactoryBean factoryBeanVO() { return new BookFactoryBean(); } public Book getObject() throws Exception {return new Book(" Red House dream ", "Chinese classic ", 88); } public Class<? > getObjectType() { return Book.class; } public boolean isSingleton() { return true; }}Copy the code

3.3 FactoryBeanConfig. Java

package com.spring.config; import com.spring.bean.BookFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FactoryBeanConfig { @Bean public BookFactoryBean bookFactoryBean() { return new BookFactoryBean(); }}Copy the code

3.4 TestFactoryBean. Java

package com.spring.test; import com.spring.config.FactoryBeanConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestFactoryBean { public static void main(String[] args) { AnnotationConfigApplicationContext annotationContext = new AnnotationConfigApplicationContext(FactoryBeanConfig.class); / / get the bean factory class Object bookFactoryBean = annotationContext. GetBean (" bookFactoryBean "); System.out.println(bookFactoryBean.getClass()); // Output result: Com.spring.bean. Book // Gets the FactoryBean itself with the & symbol Object bookFactoryBean1 = annotationContext.getBean("&bookFactoryBean"); System.out.println(bookFactoryBean1.getClass()); / / output results: class com. Spring. Beans. BookFactoryBean}}Copy the code

4. @FactoryBean application Scenario

  • Using a FactoryBean for a single object doesn’t make much sense.

  • Object creation relies on the need for other interfaces to listen for data and do some data processing based on the interface that pushes the data to it.

  • Collaborate with other interfaces and rely on the Spring lifecycle to generate the objects you need at a certain point in time and under the right conditions.

5. Typical applications

  • MyBatis3 provide mybatis – in the spring project org. Mybatis. Spring. SqlSessionFactoryBean:

  • FactoryBean is also used by Consumer in Dubbo, Alibaba’s open source distributed services framework

  • In shiro ShiroFilterFactoryBean

  • The druid JdbcStatManagerFactoryBean