Trying to setup a Spring 4 web application with Java Config, I encounter a problem with autowiring a bean created in a configuration class into another configuration class. The 'dataSource' bean has a null value in the MyBatisConfig class. This seems to be the only bean in the configuration that doesn't get wired properly. Looking at the Spring debug logs (see last part of logs in the last code block below) it looks instantiated properly, but also seems to be destroyed?. What could be wrong in my configuration?
PropertySourcesPlaceholderConfigurerConfig class:
package nl.somesite.teamshot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
@Configuration
public class PropertySourcesPlaceholderConfigurerConfig {
@Bean
public PropertySourcesPlaceholderConfigurer propertyConfigurer() {
PropertySourcesPlaceholderConfigurer propertyConfigurer = new PropertySourcesPlaceholderConfigurer();
propertyConfigurer.setLocation(new ClassPathResource("application.properties"));
/*propertyConfigurer.setLocation(new ClassPathResource("file:${catalina.home}/conf/application.properties"));
propertyConfigurer.setLocation(new ClassPathResource("/var/lib/openshift/517874b8e0b8cd218e000391/app-root/data/apache-tomcat-7.0.39/conf/application.properties"));*/
propertyConfigurer.setIgnoreUnresolvablePlaceholders(false);
propertyConfigurer.setIgnoreResourceNotFound(true);
return propertyConfigurer;
}
}
DbConfig class:
package nl.somesite.teamshot.config;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({PropertySourcesPlaceholderConfigurerConfig.class})
public class DbConfig {
private @Value("jdbc:mysql://${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/${OPENSHIFT_MYSQL_DATABASE}") String url;
private @Value("${OPENSHIFT_MYSQL_DB_USERNAME}") String username;
private @Value("${OPENSHIFT_MYSQL_DB_PASSWORD}") String password;
static Logger log = LogManager.getLogger(DbConfig.class.getName());
@Bean
public BasicDataSource dataSource() {
log.debug("Creating dataSource bean, url = "+ url);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDefaultAutoCommit(false);
log.debug("dataSource bean url = "+ dataSource.getUrl());
return dataSource;
}
}
MyBatisConfig class:
package nl.somesite.teamshot.config;
import java.io.IOException;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@Configuration
@Import({DbConfig.class})
public class MyBatisConfig {
@Autowired private BasicDataSource dataSource;
static Logger log = LogManager.getLogger(MyBatisConfig.class.getName());
@Bean
public SqlSessionFactoryBean sqlSessionFactory() {
log.debug("Creating SqlSessionFactoryBean, dataSource = " + dataSource);
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
org.springframework.core.io.Resource[] classPathResources;
try {
classPathResources = resolver.getResources("classpath*:/mappers/*.xml");
sqlSessionFactory.setMapperLocations(classPathResources);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sqlSessionFactory;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
log.debug("Creating MapperScannerConfigurer");
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("nl.somesite.teamshot.data");
return mapperScannerConfigurer;
}
}
AppConfig class:
package nl.somesite.teamshot.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"nl.somesite.teamshot.config"})
public class AppConfig {
}
AppInitializer class:
package nl.somesite.teamshot.initializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "nl.somesite.teamshot.config";
private static final String MAPPING_URL = "/";
static Logger log = LogManager.getLogger(AppInitializer.class.getName());
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(MAPPING_URL);
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation(CONFIG_LOCATION);
return context;
}
}
WebMvcConfig class:
package nl.somesite.teamshot.config;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
static Logger log = LogManager.getLogger(WebMvcConfig.class.getName());
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
Last part of logs:
[DEBUG:] 2014-07-09 01:25:20 [DefaultSingletonBeanRegistry line:220] Creating shared instance of singleton bean 'dataSource'
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:449] Creating instance of bean 'dataSource'
[DEBUG:] 2014-07-09 01:25:20 [AbstractBeanFactory line:249] Returning cached instance of singleton bean 'dbConfig'
[DEBUG:] 2014-07-09 01:25:20 [DbConfig line:25] Creating dataSource bean, url = jdbc:mysql://localhost:3306/teamshot?useUnicode=true&characterEncoding=UTF-8
[DEBUG:] 2014-07-09 01:25:20 [DbConfig line:34] dataSource bean url = jdbc:mysql://localhost:3306/teamshot?useUnicode=true&characterEncoding=UTF-8
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:523] Eagerly caching bean 'dataSource' to allow for resolving potential circular references
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:477] Finished creating instance of bean 'dataSource'
[DEBUG:] 2014-07-09 01:25:20 [DefaultSingletonBeanRegistry line:220] Creating shared instance of singleton bean 'sqlSessionFactory'
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:449] Creating instance of bean 'sqlSessionFactory'
[DEBUG:] 2014-07-09 01:25:20 [AbstractBeanFactory line:249] Returning cached instance of singleton bean 'myBatisConfig'
[DEBUG:] 2014-07-09 01:25:20 [MyBatisConfig line:27] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 01:25:20 [PathMatchingResourcePatternResolver line:553] Looking for matching resources in directory tree [D:\Eclipse workspaces\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\teamshot\WEB-INF\classes\mappers]
[DEBUG:] 2014-07-09 01:25:20 [PathMatchingResourcePatternResolver line:615] Searching directory [D:\Eclipse workspaces\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\teamshot\WEB-INF\classes\mappers] for files matching pattern [D:/Eclipse workspaces/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/teamshot/WEB-INF/classes/mappers/*.xml]
[DEBUG:] 2014-07-09 01:25:20 [PathMatchingResourcePatternResolver line:354] Resolved location pattern [classpath*:/mappers/*.xml] to resources [file [D:\Eclipse workspaces\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\teamshot\WEB-INF\classes\mappers\newsitems.xml], file [D:\Eclipse workspaces\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\teamshot\WEB-INF\classes\mappers\teams.xml]]
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:523] Eagerly caching bean 'sqlSessionFactory' to allow for resolving potential circular references
[DEBUG:] 2014-07-09 01:25:20 [AbstractAutowireCapableBeanFactory line:1595] Invoking afterPropertiesSet() on bean with name 'sqlSessionFactory'
[DEBUG:] 2014-07-09 01:25:20 [DefaultSingletonBeanRegistry line:474] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3278a91: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,dbConfig,myBatisConfig,propertySourcesPlaceholderConfigurerConfig,webMvcConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,dataSource,sqlSessionFactory,mapperScannerConfigurer,propertyConfigurer,org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration,requestMappingHandlerMapping,mvcContentNegotiationManager,viewControllerHandlerMapping,beanNameHandlerMapping,resourceHandlerMapping,defaultServletHandlerMapping,requestMappingHandlerAdapter,mvcConversionService,mvcValidator,mvcUriComponentsContributor,httpRequestHandlerAdapter,simpleControllerHandlerAdapter,handlerExceptionResolver,internalResourceViewResolver,newsItemMapper,teamMapper]; root of factory hierarchy
[DEBUG:] 2014-07-09 01:25:20 [DisposableBeanAdapter line:322] Invoking destroy method 'close' on bean with name 'dataSource'
[DEBUG:] 2014-07-09 01:25:20 [DisposableBeanAdapter line:244] Invoking destroy() on bean with name 'webMvcConfig'
[DEBUG:] 2014-07-09 01:25:20 [DisposableBeanAdapter line:244] Invoking destroy() on bean with name 'dbConfig'
[DEBUG:] 2014-07-09 01:25:21 [DisposableBeanAdapter line:244] Invoking destroy() on bean with name 'appConfig'
[DEBUG:] 2014-07-09 01:25:21 [DisposableBeanAdapter line:244] Invoking destroy() on bean with name 'propertySourcesPlaceholderConfigurerConfig'
[ERROR:] 2014-07-09 01:25:21 [ContextLoader line:331] Context initialization failed Error creating bean with name 'sqlSessionFactory' defined in class path resource [nl/somesite/teamshot/config/MyBatisConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
jul 09, 2014 1:25:21 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [nl/somesite/teamshot/config/MyBatisConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:681)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.IllegalArgumentException: Property 'dataSource' is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:337)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 22 more
If I disable Spring debug logging I see this:
[DEBUG:] 2014-07-09 11:02:19 [MyBatisConfig line:50] Creating MapperScannerConfigurer
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [DbConfig line:24] Creating dataSource bean, url = jdbc:mysql://localhost:3306/teamshot?useUnicode=true&characterEncoding=UTF-8
[DEBUG:] 2014-07-09 11:02:20 [DbConfig line:33] dataSource bean url = jdbc:mysql://localhost:3306/teamshot?useUnicode=true&characterEncoding=UTF-8
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[DEBUG:] 2014-07-09 11:02:20 [MyBatisConfig line:30] Creating SqlSessionFactoryBean, dataSource = null
[ERROR:] 2014-07-09 11:02:20 [ContextLoader line:331] Context initialization failed Error creating bean with name 'sqlSessionFactory' defined in class path resource [nl/somesite/teamshot/config/MyBatisConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
In addition to being able to reference any particular bean definition as seen above, one @Configuration class may reference the instance of any other @Configuration class using @Autowired . This works because the @Configuration classes themselves are instantiated and managed as individual Spring beans.
We can also declare beans using the @Bean annotation in a configuration class. Finally, we can mark the class with one of the annotations from the org.
@Bean methods may also be declared within classes that are not annotated with @Configuration. For example, bean methods may be declared in a @Component class or even in a plain old class. In such cases, a @Bean method will get processed in a so-called 'lite' mode.
@Willa yes, @Bean can be used in inside a class annotiated with @Component . "You can use the @Bean annotation in a @Configuration-annotated or in a @Component-annotated class." docs.spring.io/spring-framework/docs/current/reference/html/…
After reading a lot of Spring related stuff I discovered that the MapperScannerConfigurer is a implementation of BeanFactoryPostProcessor. Having a BeanFactoryPostProcessor in a @Configuration class breaks the default post-processing of that @Configuration class.
There is a fundamental lifecycle conflict in handling BeanFactoryPostProcessor @Bean methods within @Configuration classes that use @Autowired, @PostConstruct, @Value, etc. Because BFPPs must be instantiated early in the lifecycle, they cause early instantiation of their declaring @Configuration class - too early to recieve the usual post-processing by AutowiredAnnotationBeanPostProcessor and friends. See https://jira.spring.io/browse/SPR-8269
Separating the MapperScannerConfigurer bean method from MyBatisConfig into it's own class solves the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With