@Autowired
@Qualifier("cipShopOwnerServiceImpl") bean name
ShopOwnerService cipShopOwnerServiceImpl;
ShopOwnerService 需要是接口 cipShopOwnerServiceImpl bean的名字
ShopOwnerService是接口,两个实现类
@Component("cipShopOwnerServiceImpl") bean name
public class CIPShopOwnerServiceImpl implements ShopOwnerService {}
和
@Component("shopOwnerServiceImpl") bean name
public class ShopOwnerServiceImpl implements ShopOwnerService {}
直接
@Autowired
CipShopOwnerServiceImpl cipShopOwnerServiceImpl;
报错
@Autowired
// @Qualifier("cipShopOwnerServiceImpl")
ShopOwnerService cipShopOwnerServiceImpl;
可以
@Autowired
// @Qualifier("cipShopOwnerServiceImpl")
ShopOwnerService pShopOwnerServiceImpl;
报错 确定cipShopOwnerServiceImpl 最好是bean name
我们编写spring框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean都建议定义成私有的域变量。并且要配套写上get和set方法。
Boss拥有Office和Car类型的两个属性:
public class Boss
{
private Car car;
private Office office;
//省略 get/setter
@Override
public String toString()
{
return "car:" + car + "/n" + "office:" + office;
}
}
我们在Spring容器中将Office和Car声明为Bean,并注入到Boss Bean中,下面是使用传统XML完成这个工作的配置文件beans.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="boss" class="Boss">
<property name="car" ref="car"/>
<property name="office" ref="office" />
bean>
<bean id="office" class="Office">
<property name="officeNo" value="002"/>
bean>
<bean id="car" class="Car" scope="singleton">
<property name="brand" value="红旗CA72"/>
<property name="price" value="2000"/>
bean>
beans>
当我们运行以下代码时,控制台将正确打出boss的信息:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test
{
public static void main(String[] args)
{
String[] locations = {"beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);
Boss boss = (Boss) ctx.getBean("boss");
System.out.println(boss);
}
}
Spring 2.5引入了@Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowired的使用来消除set,get方法。
下面是@Autowired的定义:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
public @interface Autowired
{
//是否必须满足依赖性检查,默认时,凡是应用了@Autowired注解的属性和方法都必须找到合适的协作者,否则Spring容器会抛出异常,
//通过调整required属性取值能够改变这一行为。
boolean required() default true;
}
注意:@Autowired注解能够作用于构建器、属性、方法。这里的方法不局限于设值方法,即setter方法,常见的各种方法都可以应用这一注解。
要使用@Autowired实现我们要精简程序的目的,需要这样来处理:
在applicationContext.xml中加入:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
Spring通过一个BeanPostProcessor对@Autowired进行解析,所以要让@Autowired起作用必须事先在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean。
修改在原来注入Spirng容器中的bean的方法,在域变量上加上标签@Autowired,并且去掉相应的get和set方法。
使用 @Autowired 注释的 Boss.java
import org.springframework.beans.factory.annotation.Autowired;
public class Boss
{
@Autowired
private Car car;
@Autowired
private Office office;
}
在applicatonContext.xml中把原来引用的标签也去掉。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="boss" class="Boss"/>
<bean id="office" class="Office">
<property name="officeNo" value="001"/>
bean>
<bean id="car" class="Car" scope="singleton">
<property name="brand" value="红旗 CA72"/>
<property name="price" value="2000"/>
bean>
beans>
这样,当 Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring容器中所有Bean,当发现Bean中拥有@Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。
@Autowired默认是按照byType进行注入的,但是当byType方式找到了多个符合的bean,又是怎么处理的?Autowired默认先按byType,如果发现找到多个bean,则又按照byName方式比对,如果还有多个,则报出异常。
例子:
@Autowired
private Car redCar;
参考:
http://www.iteye.com/problems/55089
http://www.baeldung.com/spring-nosuchbeandefinitionexception
http://swiftlet.net/archives/734
http://blog.csdn.net/zhiweianran/article/details/8659944