1. @Autowired 注解的作用以及使用
@Autowired 顾名思义,就是自动装配,其作用是为了消除代码 Java 代码里面的 getter/setter 与 bean 属性中的 property。当然,getter 看个人需求,如果私有属性需要对外提供的话,应当予以保留。
因此,引入 @Autowired 注解,不要忘记配置文件要写:
<context:component-scan base-package="www.xq.spring.bean"></context:component-scan>
然后才是在 JavaBean 的属性上加注解
public class Zoo {
@Autowired
private Tiger tiger;
@Autowired
private Monkey monkey;
这里 @Autowired 注解的意思就是,当 Spring 发现 @Autowired 注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的 Bean,并自动注入到相应的地方去。
有一个细节性的问题是,假设此时我把.xml文件的
<bean id="monkey" class="www.xq.spring.bean.Monkey" p:monkeyName="mm"></bean>
<bean id="tiger" class="www.xq.spring.bean.Tiger" p:tigerName="tt"></bean>
两行给去掉,再运行,会抛出异常,因为,@Autowired 注解要去寻找的是一个 Bean,Tiger 和 Monkey 的 Bean 定义都给去掉了,Spring 容器找不到了自然抛出异常。那么,如果属性找不到对应的对象我不想让 Spring 容器抛 出异常,而就是显示 null,可以吗?可以的,就是将 @Autowired 注解的 required 属性设置为 false 即可:
注意:在使用 @Autowired 注解时,一定要保证该 bean 在 ioc 容器中,配置方式可以二选一
public class Zoo {
@Autowired(required=false)
private Tiger tiger;
@Autowired(required=false)
private Monkey monkey;
2. @Autowired 接口注入
上面的比较简单,我们只是简单注入一个Java类,那么如果有一个接口,有多个实现,Bean里引用的是接口名,又该怎么做呢?比如有一个Car接口:
public interface Car{
public String carName();
}
两个实现类:
BWMCar
@Component
public class BWMCar implements Car{
public String carName() {
return "宝马";
}
}
AudiCar
@Component
public class AudiCar implements Car {
public String carName() {
return "奥迪";
}
}
TestCar
@Component
public class TestCar {
@Autowired
@Qualifier("Audi")
private Car car;
@Override
public String toString() {
return "TestCar [car=" + car + "]";
}
}
不用说,一定是报错的,Car接口有两个实现类,Spring并不知道应当引用哪个实现类。这种情况通常有两个解决办法:
- 删除其中一个实现类,Spring会自动去base-package下寻找Car接口的实现类,发现Car接口只有一个实现类,便会直接引用这个实现类
- 实现类就是有多个该怎么办?此时可以使用@Qualifier注解,指明你要spring装载那个对象:
3. @Inject
最后提一下,还有一个功能和 @Autowired 差不多的一个注解 @inject,它是 jsr330 规范的注解,用它的话要导入相应的 jar 包,我们推荐使用 @Autowired
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>