在WebLogic中使用DataSource时遭遇NoSuchBeanDefinitionException问题求助
在WebLogic中创建的DataSource用于Spring应用时,抛出如下异常:
weblogic.application.ModuleException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
部分堆栈信息:
at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:140) at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124) at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:233) at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:228) at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45) at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:78) at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:752) at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45) at weblogic.application.internal.B
相关配置代码:
Java配置类
@Configuration @ConfigurationProperties("my.oracle") public class MyDBConfiguration { @NotNull private String jndiname; public void setJndiname(String jndiname) { this.jndiname = jndiname; } @Bean(name = "testA") @Primary public DataSource dataSource() throws SQLException{ DataSource dataSource; try { Context ctx = new InitialContext(); dataSource = (DataSource) ctx.lookup(this.jndiname); // 确认与WebLogic中JNDI名称(jdbc/myOracleDataSource)一致 return dataSource; }catch(Exception e) { e.printStackTrace(); return null; } } }
配置文件(application.local.properties)
my.oracle.jndiname=jdbc/myOracleDataSource
1. 配置类未被Spring扫描识别
如果MyDBConfiguration所在的包不在Spring组件扫描范围内,Spring不会加载这个配置类,自然不会生成DataSource Bean。
- 检查主启动类的
@SpringBootApplication或@ComponentScan注解,确保配置类所在包被覆盖; - 若不在默认扫描路径,手动在主启动类添加
@ComponentScan(basePackages = "你的配置类所在包路径")。
2. 配置属性绑定失败
@ConfigurationProperties需要对应属性的getter方法才能完成绑定,你的代码中只有jndiname的setter,没有getter,会导致属性值无法正确注入,最终JNDI查找时使用null值导致失败。
- 给
jndiname添加@Getter方法; - 可以在
dataSource()方法中打印this.jndiname的值,验证是否读取到配置文件中的jdbc/myOracleDataSource; - 若使用Spring Boot,确保引入了配置处理器依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
3. JNDI查找失败导致Bean返回null
你的代码中JNDI查找失败会返回null,Spring不会将null作为有效Bean注册,这是核心问题之一。即使你确认名称一致,仍可能存在以下问题:
- WebLogic的JNDI名称需要带上全局上下文前缀,比如
java:comp/env/jdbc/myOracleDataSource,不同版本WebLogic可能有差异; - 检查WebLogic控制台中数据源的目标JNDI名称(而非数据源名称)是否与配置一致;
- 应用部署时未关联该数据源,需在WebLogic部署配置中绑定应用与对应数据源;
- 尝试使用带环境参数的
InitialContext进行查找:
Hashtable<String, String> env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL, "t3://你的WebLogic地址:端口"); Context ctx = new InitialContext(env);
4. 异常处理掩盖真实错误
当前代码在捕获异常后仅打印日志并返回null,导致Spring无法感知到JNDI查找的真实错误,建议修改为直接抛出异常,以便启动时看到明确的错误信息:
@Bean(name = "testA") @Primary public DataSource dataSource() throws NamingException { Context ctx = new InitialContext(); return (DataSource) ctx.lookup(this.jndiname); }
5. Bean类型匹配问题
确保应用中注入DataSource的地方使用的是javax.sql.DataSource类型,而非特定实现类,避免类型不匹配导致无法找到候选Bean。
内容的提问来源于stack exchange,提问作者user1015388

