异常信息 NoSuchBeanDefinitionException: No matching bean of type [...]或是NoSuchBeanDefinitionException: No unique bean of type [...] 这二者具体区别暂不深究,但究其缘由都是由于找不到某类型的bean,后面再讲。java
异常信息 expected single matching bean but found 2,很好理解,以前是找不到,如今是找到不止一个,spring不知道该怎么办了。spring
...待补充post
这是未经考证的说法,我认为区分为这二者以后比较容易理解注入问题。严格来说注入和注出关系被以各类方式描述在了beanDefinition里面,相似于消费者和生产者。他们的行为每每发生在spring容器初始化时,除非指定为了prototype。ui
排查问题时从这两个角度来看,注入是否是不对,注出是否是不对。spa
1. 咱们必需要了解最简单直接的方式,即prototype
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" />
就这种方式而言也另有工厂方法方式,其中还分为静态工厂以及实例工厂,不细讲component
2. 在spring后续引入注解后,在对类施加@Service @Component @Controller @Repository这四种注解(他们在注出上做用同样),并配置包扫描:xml
<context:component-scan base-package="com.mypackage"/>
同时配置注解的类要在包扫面的路径以内。注解注出的bean默认的id和name是类名第一个字母改成小写blog
注入指的是通知spring你的bean对哪些bean拥有实例或称依赖,须要spring作“填充”。
继承
2.2.1.显式注入:setter注入(还有constructor注入,与此相似):
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref>dataSource</ref> </property> </bean>
setter注入须要有对应的setter方法,请注意驼峰命名,不然抛出找不到setter的异常。constructor注入须要对应的构造方法。
2.2.2.自动装配
default-autowire="byName/byType"
特别注意,这个东西和@autowire没有半毛钱关系,通常出如今spring文件头,即<beans>标签内。这个设置会智能的扫描每一个bean有哪些setter方法,并添加相似第一条的property。也就是说有此配置后就不须要上面的<property></property>标签了。不一样之处在于显式配置可自由指定所需的bean,default-autowire只有根据名称、类型来匹配。
2.2.3.注解注入
首先要启动注解注入,主要由AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及requiredAnnotationBeanPostProcessor这四个类来负责检测注解并实现注入的,因此spring容器须要获得这几个类的bean,这里有两种方式:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
使用到哪一个注解就注册对应的PostProcessor,假如使用autowired,就用这个就能够了。其余的具体对应关系请自行研究。
<context:annotation-config />
这个配置将隐式地向 Spring 容器注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及equiredAnnotationBeanPostProcessor这 4 个 BeanPostProcessor。而上述的 component-scan该配置项其实也包含了自动注入上述processor的功能,所以当使用 <context:component-scan/> 后,就能够将 <context:annotation-config/> 移除了。这是由于前者默认包含着这样一个属性:annotation-config="true",假如咱们将其显式指定为false,那么就要另外添加<context:annotation-config/>配置。
启动注解注入以后,固然要使用注解:
@autowired
@autowired 注入的注解,默认是按type注入,但能够用@Qualifier("abc")改成byname。
@Autowired setAbc(@Qualifier("abc")Abc abc)
事实证实,写在方法前面的autowire能够无视方法名,如
@Autowired public void aaa(QuestionMarkDao questionMarkDao) { super.setBaseDao(questionMarkDao); }
这样,和@postConstruct注解就相对比较接近了,不一样在于前者能够带参数,参数会自动从容器中找对应的bean
@Autowired @Qualifier("abc") MyClass myClass;
@Resource
按name来注入的注解,找不到的时候尝试按type注入。byName指的是优先byName,若是找不到与属性名称相同的bean时再按照type进行查找。这里就会出现上面讲的两个异常了,第一种是没找到相同名字、也没有相同类型( No unique bean of type );第二种是有相同名字,可是类型不一样(……);第三种是没有找到相同名字,可是相同类型的有多个( expected single matching bean but found 2)
@Resource MyClass myClass @Resource(name="otherName") MyClass myClass
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" />
须要引入xmlns以及schemaLocation
value和ref的区别:
前者是注入字符串值,后者注入容器内的bean(id为ref值的bean)