Resolving Spring Startup StackOverflowError Caused by @Autowired and MyBatis MapperFactoryBean
The article analyzes a StackOverflowError that occurs during Spring application startup after upgrading to JDK 8, tracing the deep bean‑creation call chain caused by extensive use of @Autowired with MyBatis MapperFactoryBean, and recommends upgrading mybatis‑spring and switching to @Resource to prevent the overflow.
After upgrading the production environment to JDK 8, Tomcat startup began to fail intermittently; increasing the JVM stack size reduced the frequency but did not eliminate the issue. The captured logs show a long stack trace ending with a java.lang.StackOverflowError, indicating an abnormal recursion during bean creation.
Background
The system runs on JDK 8, Tomcat 7, Spring 3.1.2.RELEASE, MyBatis‑3.0.6.jar, and MyBatis‑spring‑1.0.2.jar.
Analysis
3.1 Stack Call Analysis
The repeated stack frames belong to Spring's bean‑creation process. When a bean is instantiated, Spring traverses its dependencies; if a required bean is missing, it continues creating dependent beans, leading to a deep recursive call chain.
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(...)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(...)
... (many similar frames) ...
Caused by: java.lang.StackOverflowErrorThe chain shows a pattern like service1 → dao1 → dao2 → dao3 → …, which is impossible for MyBatis mapper interfaces that should not call each other.
3.2 @Autowired Annotation
Spring resolves @Autowired by iterating over all BeanDefinition objects, matching types, and selecting the best candidate. For FactoryBean instances, Spring must instantiate the bean to determine its actual type via getObjectType(), adding extra recursion.
3.3 MapperFactoryBean
MyBatis mapper interfaces are registered as MapperFactoryBean, which implements FactoryBean and uses @Autowired for its SqlSession. During bean creation, Spring treats each mapper as a regular bean, triggering the same @Autowired processing and extending the call stack.
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
private SqlSession sqlSession;
@Autowired(required = false)
public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { ... }
@Autowired(required = false)
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { ... }
...
}This recursive dependency resolution causes the stack depth to exceed the JVM limit as the number of mappers grows.
3.4 @Resource
Using @Resource, which resolves dependencies by bean name rather than type, avoids the exhaustive type‑matching loop, dramatically shortening the initialization call stack.
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
synchronized (this.beanDefinitionMap) {
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null && !this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(...);
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
}Conclusion
The root cause is heavy use of @Autowired together with an outdated mybatis‑spring version that still annotates MapperFactoryBean. Upgrading to a newer mybatis‑spring (and Spring) version removes the @Autowired annotation from the mapper factory, and switching injection to @Resource eliminates the deep recursive bean‑creation chain, preventing the StackOverflowError.
Recommended actions:
Upgrade mybatis‑spring, MyBatis, and Spring to recent compatible versions.
Prefer @Resource over @Autowired for mapper injection.
Review bean definitions to ensure no unnecessary circular dependencies.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
