This is the third day of my participation in Gwen Challenge

This is a common Spring interview question, and the similarity is that both can be used to create Spring-managed bean objects. But despite their similar names, they are actually two completely different things without any connection.

A, the BeanFactory

BeanFactory is a factory class. It is the root interface of the Spring Bean container. In Spring, all bean objects are produced and managed by the BeanFactory, which is also the IOC container.

The BeanFactory is just an interface, not the implementation of the IOC container, but the Spring container is given a lot of kinds of implementation, such as DefaultListableBeanFactory, XmlBeanFactory, ApplicationContext, etc.

Second, the FactoryBean

We mentioned above that both BeanFactory and FactoryBean can be used to create objects, but the difference is that BeanFactory creates objects in a tight and complex lifecycle. If we want to customize a bean object and hand it over to Spring, we need to implement the FactoryBean interface.

Take a look at its source code:

public interface FactoryBean<T> {

	/** * gets an instance of the generic T, which is used to create the Bean
	@Nullable
	T getObject(a) throws Exception;

	/** * returns the type of T, or the implementation class */ if T is an interface
	@NullableClass<? > getObjectType();/** * if the bean instance returned by FactoryBean#getObject is a singleton, then FactoryBean#getObject will only be called once */
	default boolean isSingleton(a) {
		return true; }}Copy the code

Let’s implement the following interface ourselves

public class Car {}@Component
public class MyFactoryBean implements FactoryBean<Car> {
	@Override
	public Car getObject(a) throws Exception {
		return new Car();
	}

	@Override
	publicClass<? > getObjectType() {return Car.class;
	}

	@Override
	public boolean isSingleton(a) {
		return true; }}Copy the code

Let’s print our custom bean

public class Test {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac =
			new AnnotationConfigApplicationContext(AppConfig.class);
// AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) ac.getBeanFactory();
// beanFactory.setAllowCircularReferences(false);
// ac.register(AppConfig.class);
// ac.refresh();

		System.out.println(ac.getBean("myFactoryBean")); }}Copy the code

Output result:

com.bean.Car@5c1a8622

As you can see, we are not handing over the car class to Spring, but we are implementing the FactoryBean interface with our custom bean. The FactoryBean#getObject method gets our car object. If isSingleton returns true, So every time you call getObject you get the same object back.

So what happened to our custom MyFactoryBean bean bean object? How do we get him?

ac.getBean("&myFactoryBean")

We just need to prefix beanName with the ampersand to get the object itself.

Above, thanks for reading.