“This is the fifth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

The second step in the Bean lifecycle is a factory Bean:

Is factoryBean

What is a factoryBean?

  • Factory bean.
if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<? > factory = (FactoryBean<? >) bean; boolean isEagerInit; if (System.getSecurityManager() ! = null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<? >) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<? >) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); }}}Copy the code

IsFactoryBean (beanName) :

public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); Object beanInstance = getSingleton(beanName, false); if (beanInstance ! = null) { return (beanInstance instanceof FactoryBean); } // No singleton instance found -> check bean definition. if (! containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name); } return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName)); }Copy the code

How to judge by the name?

Step 1: Try fetching it from the singleton pool and determine if it is an Instanceof factoryBean.

ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory:

So go to the parent’s BeanFactory and try the query.

That’s what MVC does, and it actually feels a little bit like parental delegation.

Step 3: If not, you can only get it from this class.

This step checks to see if it is a FactoryBean, based on BD.

When is factoryBean.getobject called?

  • It’s actually called inside the getBean of the context. Corresponding code:

     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    Copy the code

isEagerInit

If you implement SmartFactoryBean and isEagerInit= True, you go back to initialization. Otherwise, it is not initialized.

Not a factoryBean

Call getBean directly to generate the bean object.

 else {
    getBean(beanName);
 }
Copy the code

GetBean (name)

The more accurate name for this method is:

  • getOrCreateBean

The method called is actually the doGetBean() method.

From the previously parsed code, you know:

  • The name here could be $….. (This is to get a factoryBean), which can be a class name or an alias (stored in aliasMap).

The name will be in

 String beanName = transformedBeanName(name);
Copy the code

This is resolved to a canonical name.

process

The first is to go to the singleton pool and try to get:

 Object sharedInstance = getSingleton(beanName);
Copy the code

If so, this is the code for this section:

if (sharedInstance ! = null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet -  a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); }Copy the code

If you can’t get it, you have to create it.

There are two cases: singleton, but not created; And not a singleton is Prototype.

Both of these need to be created.

This corresponds to the else section below.

You can divide it into multiple parts here.

Check if it is Prototype and creating

 if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
 }
Copy the code

This has something to do with circular dependencies.

Check whether the parent beanFactory has the bean

BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory ! = null && ! containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args ! = null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType ! = null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); }}Copy the code

If the beanFactory does not exist in your BDMap and has a parent beanFactory, delegate to the parent beanFactory to create the bean.

So, if you don’t have a parent BeanFactory, you have to deal with it yourself.

Create your own

The first is of course to obtain BD, according to the previous description we also know that we need to obtain mergedBD (that is, synthesize the inheritance relationship to generate a BD containing all the information we need), and check.

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // This step will check if it is abstract BD. If it is abstract BD, it will not be able to construct a bean. checkMergedBeanDefinition(mbd, beanName, args);Copy the code

Now that you’ve got the BD, it’s time to formally go through the process of creating the bean. The process here is a bit more complicated, which we’ll leave to the next article.