跪求大神:Could not autowire field: private com.mvc.service.StudentService com.mvc.controller.Stud

Errorcreatingbeanwithname'studentController':Injectionofautowireddependenciesfailed;n... Error creating bean with name 'studentController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void
Could not autowire method: public void com.mvc.controller.StudentController.setStudentService(com.mvc.service.StudentService);
No matching bean of type [com.mvc.service.StudentService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
展开
 我来答
松鼠就是我
2018-03-30 · TA获得超过1.6万个赞
知道小有建树答主
回答量:5
采纳率:0%
帮助的人:1604
展开全部

一个Spring注入问题,首先看一个普通Spring Bean,

public class Foo {
@Autowired
Bar bar;

public void doSomething(){
bar.doSomething();
}
}

Spring配置一:

<bean id="bar" class="com.test.Bar"></bean>
<bean id="foo" class="com.test.Foo"></bean>

单元测试:

@Test
public void test_doSomthing(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-test.xml");
Foo foo = ctx.getBean(Foo.class);
foo.doSomething();
}

执行上述测试方法,报错

java.lang.NullPointerException
at com.test.Foo.doSomething(Foo.java:15)
at com.test.FooTest.test_doSomthing(FooTest.java:13)

即foo bean中的bar并未注入。

Spring配置二:

<context:component-scan base-package="com.test"></context:component-scan>

当改成配置二后执行上述单元测试方法便能成功通过。经分析日志及查看源代码,发现使用配置二时供装载了6个bean,如下所示:

DEBUG org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)  Loaded 6 bean definitions from location pattern [applicationContext-test.xml]
DEBUG org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:530)  Bean factory for org.springframework.context.support.ClassPathXmlApplicationContext@3c4e80d3: org.springframework.beans.factory.support.DefaultListableBeanFactory@14cc51c8: defining beans [bar,foo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy

而使用配置一时只有两个bean,如下所示:

DEBUG org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)  Loaded 2 bean definitions from location pattern [applicationContext-test.xml]
DEBUG org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:530)  Bean factory for org.springframework.context.support.ClassPathXmlApplicationContext@45ebbb93: org.springframework.beans.factory.support.DefaultListableBeanFactory@18481697: defining beans [bar,foo]; root of factory hierarchy

配置二执行单元测试通过的原因似乎就在于多出的这几个bean。是不是只要有context:component-scan元素在自动就会有这几个bean的产生?验证此假设

在配置一中添加一个无实际意义的context:component-scan元素,如下所示:

<context:component-scan base-package="com.nonexist"></context:component-scan>

这时执行单元测试能通过,同配置二一样也会装载6个bean。那么这6个bean中到底哪个对注入bar到Foo中起了作用呢?

经过断点调试发现是AutowiredAnnotationBeanPostProcessor bean起了作用,见输出日志:

2015-04-25 20:23:09 DEBUG org.springframework.beans.factory.annotation.InjectionMetadata.<init>(InjectionMetadata.java:60)  Found injected element on class [com.test.Foo]: AutowiredFieldElement for com.test.Bar com.test.Foo.bar
2015-04-25 20:23:09 DEBUG org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:85)  Processing injected method of bean 'foo': AutowiredFieldElement for com.test.Bar com.test.Foo.bar
2015-04-25 20:23:09 DEBUG org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:245)  Returning cached instance of singleton bean 'bar'
2015-04-25 20:23:09 DEBUG org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.registerDependentBeans(AutowiredAnnotationBeanPostProcessor.java:424)  Autowiring by type from bean name 'foo' to bean named 'bar'
2015-04-25 20:23:09 DEBUG org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)  Finished creating instance of bean 'foo'

那么直接在配置一种显式添加AutowiredAnnotationBeanPostProcessor bean呢?如下所示:

<bean id="bar" class="com.tcl.account.service.test.Bar"></bean>
<bean id="foo" class="com.tcl.account.service.test.Foo"></bean>
<bean id="autowiredAnnotationBeanPostProcessor" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>

测试会不会通过?会通过。见日志:

DEBUG org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)  Loaded 3 bean definitions from location pattern [applicationContext-test.xml]
DEBUG org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:530)  Bean factory for org.springframework.context.support.ClassPathXmlApplicationContext@7767d3c1: org.springframework.beans.factory.support.DefaultListableBeanFactory@1924ed52: defining beans [bar,foo,autowiredAnnotationBeanPostProcessor]; root of factory hierarchy
DEBUG org.springframework.beans.factory.annotation.InjectionMetadata.<init>(InjectionMetadata.java:60)  Found injected element on class [com.test.Foo]: AutowiredFieldElement for com.test.Bar com.test.Foo.bar
DEBUG org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:85)  Processing injected method of bean 'foo': AutowiredFieldElement for com.test.Bar com.test.Foo.bar
DEBUG org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:245)  Returning cached instance of singleton bean 'bar'
DEBUG org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.registerDependentBeans(AutowiredAnnotationBeanPostProcessor.java:424)  Autowiring by type from bean name 'foo' to bean named 'bar'
DEBUG org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)  Finished creating instance of bean 'foo'

那么为什么在配置文件中添加了context:    componet-scan元素后就会自动添加那另外4个bean呢?经过断点调试发现Spring隐式装载的4个bean是在如下方法中加载的:

Set<BeanDefinitionHolder>  org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source)

其调用链如下所示:

补充一:

若仍用配置一,但单元测试改成如下形式也可以测试通过。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-test.xml" })
public class FooTest2 {
@Autowired
private Foo foo;
@Test
public void test_doSomthing(){
foo.doSomething();
}
}

当然一点都不意外,这种方式也会隐式加载那4个bean,见日志:

DEBUG org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)  Loaded 2 bean definitions from location pattern [classpath:/applicationContext-test.xml]
INFO  org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:500)  Refreshing org.springframework.context.support.GenericApplicationContext@51f3336e: startup date [Sun Apr 26 17:27:35 CST 2015]; root of context hierarchy
DEBUG org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:530)  Bean factory for org.springframework.context.support.GenericApplicationContext@51f3336e: org.springframework.beans.factory.support.DefaultListableBeanFactory@4f9d1352: defining beans [bar,foo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy

补充二,若使用的是@Value,效果同@Autowired,即也需要隐式加载AutowiredAnnotationBeanPostProcessor bean。

public class Foo {
@Value("${bar}")
String bar;

public void doSomething(){
System.out.println(bar);
}
}

补充三:

若使用配置一,@PostConstruct标注的方法也不会被执行,但此时需要隐式加载的Spring bean是:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

补充四:

在配置一中添加如下配置

<context:annotation-config/>

也会隐式加载那4个bean

Storm代理
2023-07-25 广告
StormProxies是一家提供动态代理服务器服务的企业,旨在帮助用户更好地管理网络访问和安全。以下是一些关于StormProxies的IP动态代理服务的特点:1. 高匿名性:StormProxies的动态代理服务器具有高匿名性,可以有效... 点击进入详情页
本回答由Storm代理提供
我爱学习123666
2013-05-15
知道答主
回答量:4
采纳率:0%
帮助的人:5902
展开全部
bean的类型出错啊,studentservice里面有错,把代码贴出来看看
更多追问追答
追问

以前总是使用SSH,看到网上的Spring MVC想自己试试,结果直接项目就启不来!

追答
这个studentController类型是错误的,你是不是在studentService中写错了,你发个实现类给我看也没有用啊
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2013-05-15
展开全部
spring 配置文件 的 bean 自动注入失败! 你可以考虑 用 构造器<constructor-arg 注入 或者是 Set 注入,试试!
更多追问追答
追问
我是小菜,现在只是在学习Spring MVC注解方式,这些错误我自己看的懂,就是不知道代码要怎么修改!
追答
Could not autowire method: public void com.mvc.controller.StudentController.setStudentService(com.mvc.service.StudentService);
。。。问题 应该在StudentController 类里!下面两个类我看了,没问题的!
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式