Backend Development 13 min read

Understanding Spring’s FactoryBean and MyBatis Integration: From BeanFactory to MapperFactoryBean

This article explains how Spring’s FactoryBean mechanism enables seamless integration with MyBatis by detailing the roles of BeanFactory, SqlSessionFactoryBean, MapperScannerConfigurer, and MapperFactoryBean, and provides annotated code examples and XML configuration to illustrate the underlying process and its benefits for transaction management and thread safety.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Spring’s FactoryBean and MyBatis Integration: From BeanFactory to MapperFactoryBean

Starting from BeanFactory , we gradually analyze the working principle of Mybatis-starter , revealing how Spring integrates with Mybatis .

Preface

In the column "Mybatis Source Code Analysis" the author previously used four lines of Mybatis code to demonstrate its internal workings; readers can refer to that column for the full source.

Entry point: the four lines of Mybatis code.
//<1> Load configuration file
  InputStream is = Resources.getResourceAsStream("mybatis.xml");
  //<2> Create SqlSessionFactory object
  sessionFactory = new SqlSessionFactoryBuilder().build(is);
  //<3> Obtain SqlSession object
  SqlSession session = factory.openSqlSession();
  //<4> Build mapper proxy object
  UserMapper mapper = session.getMapper(UserMapper.class);
  // ... call related methods

We now focus on the Mybatis-starter implementation, i.e., how Spring integrates Mybatis behind the scenes.

FactoryBean

FactoryBean – the extension point that Spring leaves for external frameworks.

FactoryBean is a special type of Spring bean that can register two beans in the container: the FactoryBean itself and the object returned by its getObject() method.

In plain terms, FactoryBean lets developers customize the creation and configuration of bean instances, making the bean creation process more flexible and extensible.

Example:

public class CustomerFactoryBean implements FactoryBean
{
    @Override
    public UserService getObject() throws Exception {
        return new UserService();
    }
}

When the container processes this class, two beans are created: one of type FactoryBean named customerFactoryBean , and another of type UserService also named customerFactoryBean . Retrieving the bean without a leading '&' returns the UserService instance; to obtain the factory itself, use applicationContext.getBean("&customerFactoryBean") .

Spring Integration with Mybatis – Configuration

The typical XML configuration ( applicationContext.xml ) includes data source definition, SqlSessionFactoryBean setup, and MapperScannerConfigurer for automatic mapper scanning:

This configuration performs three main tasks: specify the data source, create a SqlSessionFactory bean, and register a MapperScannerConfigurer that scans the given package for mapper interfaces.

How MapperScannerConfigurer Works

The class implements BeanDefinitionRegistryPostProcessor , allowing it to register new bean definitions during container startup. Its postProcessBeanDefinitionRegistry method creates a ClassPathMapperScanner to scan the basePackage and register MapperFactoryBean definitions for each mapper interface.

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // ...
    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
    scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,
        ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
}

Each scanned mapper interface is wrapped in a MapperFactoryBean , which itself is a FactoryBean .

Inside MapperFactoryBean

MapperFactoryBean
public class MapperFactoryBean
extends SqlSessionDaoSupport implements FactoryBean
{
    @Override
    public T getObject() throws Exception {
        return getSqlSession().getMapper(this.mapperInterface);
    }

    @Override
    public Class
getObjectType() {
        return this.mapperInterface;
    }

    @Override
    public boolean isSingleton() {
        // return true to make the mapper a singleton
        return true;
    }
}

The getObject() method returns a MyBatis mapper proxy obtained from the SqlSession . The underlying SqlSession is actually a SqlSessionTemplate , which ensures transaction management and thread‑safety by delegating to Spring’s transaction manager.

Summary

Spring’s integration with MyBatis relies heavily on the flexible FactoryBean mechanism: SqlSessionFactoryBean creates the SqlSessionFactory , while MapperScannerConfigurer automatically registers MapperFactoryBean instances for each mapper interface, allowing seamless proxy creation, transaction handling, and thread‑safe operation.

Final Thoughts

Although source‑code analysis can be tedious, understanding these internals helps developers write more robust applications and appreciate the power of Spring’s extension points.

JavaIntegrationBackend DevelopmentSpringMyBatisFactoryBeanMapper
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.