【发布时间】:2017-01-18 20:12:17
【问题描述】:
我正在开发一种解决方案,以在 SmsService 中实现多个提供程序。我需要一种从我的上下文中注入策略类的方法。问题是选择取决于外部属性。当我尝试部署此代码时,我得到了
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type
这里我给你看我的代码:
提供者接口
public interface SmsProvider {
public Integer send(String user, String password,List<Sms> list);
}
上下文类
@Component
public class ContextProvider {
private @Inject
MessageDAO messageDAO;
private @Inject
SmsProvider strategy;
public Integer send(String user,String password) {
List<Sms> list = extractSmsList();
return strategy.send(user,password, list);
}
public void setStrategy(SmsProvider strategy) {
this.strategy = strategy;
}
策略A
@Component("provider1")
public class Provider1 implements SmsProvider {
private @Inject
MessageDAO messageDAO;
public Integer send(String user, String password, List<Sms> list) {
Status serviceErrorStatus = messageDAO.find(Status.class, 400);
...
}
策略 B
@Component("provider2")
public class Provider2 implements SmsProvider{
private @Inject
MessageDAO messageDAO;
@Override
public Integer send(String user, String password, List<Sms> list) {
Status serviceErrorStatus = messageDAO.find(Status.class, 400);
...
}
使用策略。 在这个类中,我得到属性并在 switch 子句中选择策略。
@Component
public class SmsServiceImpl implements SmsService{
@Value("${net.mycompany.sms.service.smsProvider}")
private int smsProvider;
private @Inject
MessageDAO messageDAO;
private @Inject
ContextProvider context;
....
public Integer send(String user,String password) {
LOG.debug("Sms provider property setted at: '{}'",smsProvider);
switch (smsProvider) {
case 1:
context.setStrategy(new Provider1());
return context.send(user, password);
case 2:
context.setStrategy(new Provider2());
return context.send(user, password);
}
}
我还尝试删除策略类中的 @Component 和 Context 类中 smsProvider 声明中的 @Inject,我在 Dao 类中得到 NullPointerException 和我真的需要这个 daos。 我正在使用 Spring 3.2.16-RELEASE 和 Java 7.0.15 请帮忙。任何指针都会有所帮助 提前致谢
编辑 我在 tomcat 6 服务器中添加了堆栈跟踪:
14:58:48.044 - mycompany_myCompanyFramework_Init[ERROR] - [main] ERROR o.s.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'smsBC': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.service.MessageService net.mycompany.mc.messaging.sms.bc.SmsBCImpl.smsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'smsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.impl.ContextProvider net.mycompany.mc.messaging.sms.service.impl.SmsServiceImpl.context; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) ~[spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) ~[spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at net.mycompany.mycompanyframework.component.web.spring.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:37) [mycompanyFramework-web-3.4.5.jar:na]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210) [catalina.jar:6.0.39]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4709) [catalina.jar:6.0.39]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) [catalina.jar:6.0.39]
at org.apache.catalina.core.StandardHost.start(StandardHost.java:822) [catalina.jar:6.0.39]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) [catalina.jar:6.0.39]
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) [catalina.jar:6.0.39]
at org.apache.catalina.core.StandardService.start(StandardService.java:525) [catalina.jar:6.0.39]
at org.apache.catalina.core.StandardServer.start(StandardServer.java:754) [catalina.jar:6.0.39]
at org.apache.catalina.startup.Catalina.start(Catalina.java:595) [catalina.jar:6.0.39]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_15]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_15]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_15]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_15]
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) [bootstrap.jar:6.0.39]
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) [bootstrap.jar:6.0.39]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.service.MessageService net.mycompany.mc.messaging.sms.bc.SmsBCImpl.smsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'smsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.impl.ContextProvider net.mycompany.mc.messaging.sms.service.impl.SmsServiceImpl.context; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 29 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'smsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.impl.ContextProvider net.mycompany.mc.messaging.sms.service.impl.SmsServiceImpl.context; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:912) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 31 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.impl.ContextProvider net.mycompany.mc.messaging.sms.service.impl.SmsServiceImpl.context; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 42 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contextProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:912) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 44 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.mycompany.mc.messaging.sms.service.SmsProvider net.mycompany.mc.messaging.sms.service.impl.ContextProvider.strategy; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 55 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.mycompany.mc.messaging.sms.service.SmsProvider] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489) ~[spring-beans-3.2.6.RELEASE.jar:3.2.6.RELEASE]
... 57 common frames omitted
【问题讨论】:
标签: java spring dependency-injection strategy-pattern