使用@Any注解注入Bean时遭遇NoSuchBeanDefinitionException错误求助
NoSuchBeanDefinitionException for javax.enterprise.inject.Instance in Spring Hey there, let's break down why you're hitting this error and how to fix it quickly.
The Root Cause
You're using CDI (Contexts and Dependency Injection) API components like @javax.enterprise.inject.Any and javax.enterprise.inject.Instance, but Spring's container doesn't natively provide a bean for Instance—that's a type defined by the CDI specification, not Spring's core framework. Spring has its own equivalents for this kind of dynamic dependency lookup.
Solution 1: Use Spring's Native ObjectProvider (Recommended)
Spring's ObjectProvider<T> is the direct replacement for CDI's Instance<T>. It supports all the features you probably need: lazy bean retrieval, fetching multiple beans of a type, and working with qualifiers.
Here's how to adjust your code:
import org.springframework.beans.factory.ObjectProvider; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.util.stream.Collectors; import java.util.List; @Named @Singleton public class ProcessorFactoryImpl implements ProcessorFactory { // Replace Instance<T> with ObjectProvider<T> @Inject private ObjectProvider<YourProcessorInterface> processorProvider; // Example usage: Get all qualifying processors public List<YourProcessorInterface> getAllProcessors() { return processorProvider.stream().collect(Collectors.toList()); } // Or get a single bean if you need it public YourProcessorInterface getProcessor(String beanName) { return processorProvider.getBean(beanName); } }
If you need to mimic the @Any behavior (fetch all beans of the type regardless of qualifiers), ObjectProvider's stream() method will do exactly that—it returns all beans that match the generic type.
Solution 2: Add CDI Container Integration (Only If Necessary)
If you absolutely must stick with CDI's Instance API (e.g., for cross-compatibility with other CDI-based systems), you can integrate a CDI container like Weld with Spring. Note that this adds complexity and potential conflicts, so only go this route if you have no other option:
- Add the Weld dependency to your pom.xml (if using Maven):
<dependency> <groupId>org.jboss.weld.se</groupId> <artifactId>weld-se-core</artifactId> <version>4.0.3.Final</version> </dependency>
- Configure Spring to recognize CDI beans. You'll need to add a
Beanthat initializes the Weld container and exposesInstanceas a Spring bean. However, this approach can lead to duplicate bean management (both Spring and Weld managing beans), so test thoroughly.
Key Takeaway
Spring and CDI are two different dependency injection frameworks. Stick with Spring's native components like ObjectProvider or List<T> for dependency lookup unless you have a strict requirement to use CDI APIs. This will keep your code simpler and avoid integration headaches.
内容的提问来源于stack exchange,提问作者javaq

