Spring创建dataSource Bean报错:找不到javax.sql.DataSource类型合格Bean
解决SpringSecurity中无法注入DataSource Bean的问题
嘿,我来帮你搞定这个No qualifying bean of type 'javax.sql.DataSource' available的报错!这个问题大概率是Spring容器的层次结构导致的,咱们一步步拆解解决:
问题到底出在哪?
在Spring MVC应用里,其实有两个核心容器:
- Root ApplicationContext:负责全局Bean的管理,比如数据源、事务管理器、Spring Security这类全局组件都应该放在这里,它是父容器
- Web ApplicationContext:专门管Web层的Bean,比如控制器、视图解析器,它是子容器,能访问父容器的Bean,但父容器反过来访问不了子容器的
你的ShoppingServletConfig加了@EnableWebMvc,属于Web容器的配置类,里面定义的dataSource自然就在子容器里;而SpringSecurityConfig作为安全配置,默认是被Root容器加载的——父容器拿不到子容器里的Bean,所以就报找不到dataSource的错了。
怎么解决?
方案1:把DataSource移到Root容器(推荐,符合Spring规范)
咱们创建一个专门的Root配置类,把数据源这类全局Bean放到这里:
@Configuration @EnableTransactionManagement @ComponentScan(basePackages = "com.project.shopping", excludeFilters = @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)) public class RootConfig { @Primary @Bean(name = "dataSource") public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/shopping"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; } }
然后修改你的ShoppingServletConfig,去掉数据源的定义,只保留Web相关配置:
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.project.shopping", includeFilters = @Filter(type = FilterType.ANNOTATION, value = Controller.class)) public class ShoppingServletConfig { // 这里可以放视图解析器、消息转换器这类Web层配置 }
最后要确保web.xml里配置了ContextLoaderListener来加载RootConfig:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>com.project.shopping.RootConfig</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>com.project.shopping.ShoppingServletConfig</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
方案2:让SpringSecurity被Web容器扫描(不推荐)
如果暂时不想调整容器结构,你可以修改ShoppingServletConfig的ComponentScan范围,确保SpringSecurityConfig所在的包被包含进去,这样Web容器就能加载安全配置,同时也能拿到里面的dataSource。不过这种方式打破了Spring的容器分层设计,后续可能引发其他问题,所以优先选方案1。
最后再检查几个点
- 确认
SpringSecurityConfig所在的包在com.project.shopping下面,或者被ComponentScan覆盖到了 - 你代码里的
@Qualifier("dataSource")和Bean的name是一致的,这部分没问题 - 别忘了引入
BasicDataSource的依赖(比如commons-dbcp或者commons-dbcp2),不然数据源Bean也创建不了
内容的提问来源于stack exchange,提问作者Bishwa Karki
相关产品推荐
相关产品推荐

