Spring Source Learning Extension Points in Bean Creation

Keywords: Programming Spring Mybatis

Introduction

Tired of going to work.
Everything is boring.
Write an article
Deliver on promises

One picture wins all


The green part is generally used for Spring internal extensions, while the yellow part can be used for custom instantiation. This article just talks about Initializing Bean. For the green part, I suggest you check out blog s written by others. https://my.oschina.net/xiaolyuh/blog/3113215

InitializingBean interface

Interface notes

/**
 * 1. The interface implemented is a Bean, triggered by BeanFactory after setting all its properties.
 * 2. Can be used to perform custom instantiation or verify whether the necessary properties are set.
 * Note: Another way to implement Initializing Bean is to
 *    Develop a custom init method.
 *    Using the init-method of the < bean > element or the @PostConstruct annotation
*/
public interface InitializingBean {
   void afterPropertiesSet() throws Exception;
}

Examples of application

When looking for specific examples, I found the SqlSessionFactoryBean class used in the combination of mybatis and Spring, which is implemented as follows:

public class SqlSessionFactoryBean implements 
FactoryBean<SqlSessionFactory>, 
InitializingBean, ApplicationListener<ApplicationEvent> {
    public void afterPropertiesSet() throws Exception {
      notNull(dataSource, "Property 'dataSource' is required");
      notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
      state((configuration == null && configLocation == null) 
      || !(configuration != null && configLocation != null),
  "Property 'configuration' and 'configLocation' can not specified with together");
  this.sqlSessionFactory = buildSqlSessionFactory();
}
    
   //Eliminate other implementations...
   }

The implementation of the afterProperties Set is very simple, which is to create the SqlSessionFactory. I was more curious about the FactoryBean interface than about the afterProperties Set. When I read the comment of FactoryBean carefully, I found that the graph above lacked an important extension point.

Another important extension FactoryBean

To solve the complex problem of instantiating Bean process, we can customize the logic of instantiating Bean with FactoryBean interface.
Although FactoryBean is defined in the style of a bean, it always exposes the objects created by getObject(). Wen Anshi summarized in 1911 013

FactoryBean's programming contract is as follows

  1. Its implementation should not rely on annotation injection or other reflection tools
  2. The calls to getObjectType(), getObject() precede service startup or even any post-processor
  3. If you need to get other beans, you need to implement the BeanFactoryAware interface and manually program to get other beans.
  4. Finally, FactoryBean objects participate in the synchronous creation of bean s by BeanFactory, usually without internal synchronization, except when the FactoryBean itself is lazily loaded.

Philological Translation

/**
 *  1. This interface is implemented by a bean, which is used in conjunction with BeanFactory.
 *  2. It is itself a factory of individual objects.
 *  3.FactoryBean Supports singletons and prototypes, and can provide lazy loading or early exposure on startup as needed.
 *  4. SmartFactoryBean Allow more fine-grained behavior metadata to be exposed
 *  5.Spring The framework itself uses this interface extensively.
 *   For example {@link org.spring framework.aop.framework.ProxyFactoryBean},
 * {@link org.springframework.jndi.JndiObjectFactoryBean}. 
 */
public interface FactoryBean<T> {

   /**
    * Returns an instance managed by the current factory (possibly shared or independent)
    * Combine with BeanFactory to support singleton, prototype mode.
    * If FactoryBean is not fully loaded when it is called (for example, there is a circular reference)
    * FactoryBeanNotInitialized Exception will be thrown.
    * Spring 2.0 After that, FactoryBeans allows null to be returned.
    * When null is returned, instead of throwing FactoryBean NotInitialized Exception,
    * FactoryBean The implementation will depend on the situation.
    *Whether to throw FactoryBean NotInitialized Exception
    * BeanFactory This situation must be taken into account in the implementation.
    */
   @Nullable
   T getObject() throws Exception;

   /**
    * Return the type of the object created by FactoryBean if null is not known in advance
    *Allows you to check for specific types of bean s when instantiating objects (for example, when used for automatic assembly).
    *When creating the implementation of singleton objects, this method should avoid singleton creation as much as possible, and it should estimate the type in advance.
    *When creating object s of primitive types, it is also recommended to return meaningful type information.
    *This method can be called before FactoryBean is completely instantiated. It cannot depend on initialization.
    *Note: Auto-injection simply ignores factoryBean, which returns null.
    *Therefore, it is strongly recommended that this approach be implemented correctly using the current state of factorybean.
    */
   @Nullable
   Class<?> getObjectType();

   /**
    * When true is returned, getobject ()
    * The same object will always be returned.
    * Note: If a factorybean saves a single object,
    * Objects returned from getObject ()
    * It may be cached by the BeanFaFactory that owns it.
    * factorybean The singleton state of itself is usually determined by the BeanFactory that owns it.
    */
   default boolean isSingleton() {
      return true;
   }

}

Difference between BeanFactory and FactoryBean

Interface name BeanFactory FactoryBean
purpose BeanFactory is the top-level interface of the IOC container. Its responsibilities include instantiating, locating, configuring objects in applications, and establishing dependencies among them. Solve the problem that the process of instantiating a Bean is complex. Customize the logic of instantiated beans by implementing this interface
Objects of management All bean Objects created by the getObject method

Posted by toniknik1982 on Sun, 13 Oct 2019 06:50:57 -0700