您的位置:首页 > 其它

Sping之自动注入-1

2016-01-21 23:39 302 查看
最近终于能静下心来、一步步的学习Java Web开发。在学习的过程中,遇到太多的问题。一开始好些问题真是不知道怎么解决。在这里要非常感谢《Sping In Action》一书的作者,感谢他能写出此书,让我受益匪浅,您辛苦了!




本着“相互学习、共同进步”的原则,从今天开始,决定把自己遇到的问题,以及解决的方法都分享给大家。好以就不废话了,开始今天的分享。

今天在学习Spring以注解方式注入时,报以下错误:

th03::MianRun::run()

一月 21, 2016 11:16:01 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@790f3a9c: startup date [Thu Jan 21 23:16:01 CST 2016]; root of context hierarchy

一月 21, 2016 11:16:01 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [th03/spring.xml]

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testcls1': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not
autowire field: th03.TestCls2 th03.TestCls1.m_cls2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [th03.TestCls2] found for dependency: expected at least 1 bean which qualifies as autowire candidate
for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)

at th03.MainRun.run(MainRun.java:19)

at kpy.SpringInAction.App.th_run(App.java:22)

at kpy.SpringInAction.App.main(App.java:18)

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: th03.TestCls2 th03.TestCls1.m_cls2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [th03.TestCls2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)

... 15 more

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [th03.TestCls2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)

... 17 more

我的代码如下:

//TestCls2.java
package th03;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
public class TestCls2 {

void func1 () {
System.out.println("TestCls2::func1 ()");
}

}
TestCls1.java

package th03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
public class TestCls1 {

@Autowired
TestCls2 m_cls2;

void func1 () {
System.out.println("TestCls1::func1 ()");

m_cls2.func1();
}
}


主函数为

package th03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import kpy.SpringInAction.Th00;

public class MainRun implements Th00{

@Autowired
TestCls1 m_cls;

public void run () {

System.out.println("th03::MianRun::run()");

ApplicationContext context = new ClassPathXmlApplicationContext("/th03/spring.xml");

this.m_cls  = (TestCls1)context.getBean("testcls1");
this.m_cls.func1();
}
}


spring.xml文件内容为
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd" >

<!--
<context:annotation-config />
-->

<!-- 定义自动注入功能搜索主包名 -->
<!-- 以下这样配置要报错
<context:component-scan base-package="th03.*" />
-->
<context:component-scan base-package="th03" />

<!--  -->
<bean id="testcls1" class="th03.TestCls1" />

</beans>


错误其实就是spring.xml中红色标记的那一句。在一个项目中,这样的配置,th03.*表示th03包以及子包。但不晓得这里为什么不行(这个问题先记着吧,后续再解决



另外在MainRun中,已经对TestCls1标记为自动注入了,为什么还要以下这一句。

this.m_cls  = (TestCls1)context.getBean("testcls1");
个人解理是,由于在实现化MainRun这个类的实例时,还没有加载spring.xml,所以Java虚拟机并不知道怎么去实例化,因此用null去注入的(可以在类构造中进行new,再检查成员是否为null)。所以才在加载XML后,加了这一句。

另外,经测试,把这一句换成

this.m_cls = new TestCls1();

也是不行的。经@Autowired标注后的对象,已经注解包装后的类型,不能用原始类型(这里的TestCls1)去赋值。这纯属个人对于C++方面的知识的猜想,后续看了@autowired源码就能确认了吧。

注意:

自动注入功能,需要经spring配置文件中添加

xmlns:context="http://www.springframework.org/schema/context"

这个,不然后抛出以下异常

Caused by: org.xml.sax.SAXParseException; lineNumber: 23; columnNumber: 49; 元素 "context:component-scan" 的前缀 "context" 未绑定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: