Spring has two interfaces, BeanFactory and FactoryBean, which are very similar in name and easy to confuse.

A, the BeanFactory

BeanFactory is an interface that is the top-level specification for factories in Spring. It is the core interface of the SpringIoc container and defines common methods for managing beans such as getBean() and containsBean(). Spring’s containers are all implementations of it such as:

  • DefaultListableBeanFactory

  • XmlBeanFactory

  • ApplicationContext

These implementation classes in turn have different extensions from different dimensions.

1.1, the source code

public interface BeanFactory {

	// Escape the FactoryBean definition, because if a FactoryBean is retrieved using the bean name, the result is a factory-generated object,
	// If you want to get the factory itself, you need to escape
	String FACTORY_BEAN_PREFIX = "&";

	// Based on the bean name, get the bean instance in the IOC container
	Object getBean(String name) throws BeansException;

	// Get the bean instance according to the bean name and Class type, add type safety verification mechanism.
	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	// Provide a retrieval of the bean to see if there is a bean with this name in the IOC container
	boolean containsBean(String name);

	// Get the bean instance based on the bean name and determine whether the bean is a singleton
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, @Nullable Class
        typeToMatch) throws NoSuchBeanDefinitionException;

	// Get the Class type of the bean instance
	@NullableClass<? > getType(String name)throws NoSuchBeanDefinitionException;

	// Get the alias of the bean, and its original name will also be retrieved if retrieved by the alias
	String[] getAliases(String name);
}
Copy the code

1.1. Application Scenarios

  • Get beans (byName or byType) from the Ioc container
  • Retrieves whether the specified Bean is contained in the Ioc container
  • Determine whether the Bean is a singleton

Second, the FactoryBean

It is a Bean first, but not just a Bean. It is a factory Bean that produces or decorates object generation, similar to the Factory and decorator patterns in design patterns. It can produce an object when needed, and not just itself, it can return an instance of any Bean.

2.1, the source code

public interface FactoryBean<T> {

	// Get the bean from the factory
	@Nullable
	T getObject(a) throws Exception;

	// Gets the type of the object created by the Bean factory
	@NullableClass<? > getObjectType();// Whether the object created by the Bean factory is a singleton
	default boolean isSingleton(a) {
		return true; }}Copy the code

As you can see from the interface it defines, a FactoryBean represents the responsibilities of a factory. That is, if A Bean A implements the FactoryBean interface, then A becomes A factory. The name of A is actually the object returned by the factory call to getObject(), not A itself. If you want to get an instance of factory A itself, you need to prefix the name with an am&.

  • GetObject (‘name’) returns the instance in the factory
  • GetObject (‘&name’) returns an instance of the factory itself

In general, beans don’t have to implement the factory pattern themselves; the Spring container acts as the factory; But in rare cases, the beans in the container are factories themselves, producing other bean instances. Other bean instances produced by the factory bean are no longer produced by the Spring container, so class elements are no longer required, unlike normal bean configurations.

2.2, the sample

Start by defining a Bean that implements the FactoryBean interface

@Component
public class MyBean implements FactoryBean {
    private String message;
    public MyBean(a) {
        this.message = "Initialize instance by constructor";
    }
    @Override
    public Object getObject(a) throws Exception {
        It is not necessary to return an instance of MyBean itself; it can be an instance of any other object.
        //如return new Student()...
        return new MyBean("Create an instance from FactoryBean.getobject ()");
    }
    @Override
    publicClass<? > getObjectType() {return MyBean.class;
    }
    public String getMessage(a) {
        returnmessage; }}Copy the code

MyBean implements two methods of the FactoryBean interface. GetObject () returns an instance of any object. Here the test returns MyBean itself and assigns a value to the Message field before returning. We also assign a value to message in the constructor. The test code then gets the Bean instance by name, prints the message content, and then gets the instance by &+ name and prints the Message content.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class FactoryBeanTest {
    @Autowired
    private ApplicationContext context;
    @Test
    public void test(a) {
        MyBean myBean1 = (MyBean) context.getBean("myBean");
        System.out.println("myBean1 = " + myBean1.getMessage());
        MyBean myBean2 = (MyBean) context.getBean("&myBean");
        System.out.println("myBean2 = " + myBean2.getMessage());
        System.out.println("myBean1.equals(myBean2) = "+ myBean1.equals(myBean2)); }}Copy the code
MyBean1 = instantiate myBean2 by factoryBean.getobject () = instantiate myBean1.equals(myBean2) by constructor =false
Copy the code

2.3 Application Scenarios

So why are there factorybeans? What do they do? One of the most typical uses of FactoryBeans in Spring is to create proxy objects for AOP.

We know that AOP actually means that Spring creates a proxy object at run time, that is, the object is created at run time rather than defined from the start, which fits nicely with the factory method pattern. More graphically, AN AOP proxy object creates a proxy object at run time through Java’s reflection mechanism, with methods woven into the target methods of the proxy object based on business requirements. This object in Spring is ProxyFactoryBean.

So, FactoryBeans give us a more flexible way to instantiate beans, and we can create more complex Bean instances from FactoryBeans.

Third, the difference between

  • They’re both factories, butFactoryBeanIt’s essentially a BeanBeanFactorymanagement
  • BeanFactoryIs the top-level interface of the Spring container,FactoryBeanMore like a user-defined factory interface.

conclusion

The difference between BeanFactory and FactoryBean can be confusing, and rote memorization is not enough. It is best to understand it from the source level and in the Spring environment.

Reference: www.cnblogs.com/yulinfeng/p… www.cnblogs.com/guitu18/p/1…