Spring 利用依赖注入(DI), 为 Spring IoC 容器赋值。
@Autowired 是 Spring 自己实现的一个注解
@Qualifier
@Primary
在平时开发时,经常会在 Controller 层注入 Service , Service 层注入 DAO。 这时,我们使用最多的就是 @Autowired 注解进行注入。
@Autowired 注解
属性: required 取值为 true 和 false
true : 必须注入,默认。没有 bean 装配上, Spring IoC 容器启动报错
false : 非必须注入,没有 bean 装配,Spring IoC 容器顺利启动,不会报错
@Autowired 注解可以标注在 属性、方法、构造器上,用法基本一样
配置类
@Configuration
@ComponentScan("me.sjl.*")
public class AutoConfig {
}
Controller 代码
@Controller
public class BusinessController {
@Autowired
private BusinessService service;
public void request() {
System.out.println(" 调用了 Controller 的 request() 方法...");
service.service();
}
}
Service 代码
@Service
public class BusinessService {
@Autowired
private BusinessDAO businessDAO;
public void service() {
System.out.println("调用了 service 层的 service() 方法 .....");
businessDAO.update();
}
}
上面这种情况,很容易就能将 Bean 注入,因为我们只有一个 Service 和 Dao。
如果我们有两个 DAO 如何注入呢。
配置类
@Configuration
@ComponentScan("me.sjl.*")
public class AutoConfig {
@Bean
public BusinessDAO businessDAO) {
return new BusinessDAO();
}
}
这时我们配置了一个 bean , 使用注解产生了一个 bean, 启动 Spring 容器不会报错。
此时 IoC 容器中有两个类型相同名称相同的 bean , IoC 容器会用后面产生的 bean 来覆盖前面产生的 bean , 此时还是可以将 bean 成功注入。
将 @Bean 配置的名称修改,与 @Repository 的名称不一致。
配置类
@Configuration
@ComponentScan("me.sjl.**")
public class AutoConfig {
@Bean
public BusinessDAO dao() {
System.out.println(" 配置 bean 产生的 DAO .............");
return new BusinessDAO();
}
}
这时,启动 Spring 就报错,Spring IoC 容器不会去进行覆盖操作,此时容器中有两个相同类型的 bean , Spring IoC 容器无法确定装配哪一个 bean 所以,启动报错。
此时的解决方案: 使用 @Qualifier 注解,指定装配的 bean 的名称或者修改
Service 代码
@Service
public class BusinessService {
@Qualifier("dao")
@Autowired
private BusinessDAO businessDAO;
public void service() {
String daoName = businessDAO.getDaoName();
System.out.println(daoName);
}
}
使用了 @Qualifier 注解指定 bean 名称
如果不想使用 @Qualifier 注解指定 bean 名称,可以修改成员变量的变量名,使变量名和 bean 名称一致,也可以自动装配上。
Service 代码
@Service
public class BusinessService {
@Autowired
private BusinessDAO dao;
public void service() {
String daoName = dao.getDaoName();
System.out.println(daoName);
}
}
另外,还可以 使用 @Primary 注解,指定一个首选 bean。
DAO 代码
@Primary
@Repository
public class BusinessDAO {
private String daoName;
public String getDaoName() {
return daoName;
}
public void setDaoName(String daoName) {
this.daoName = daoName;
}
}
在 BusinessDAO 上打上 @Primary 注解,即指定了该 Bean 为首选。如果不使用 @Qualifier 注解指定 bean 名称,那么默认就将打上 @Primary 注解的 bean 进行注入,如果使用了 @Qualifier 注解,那么还是按照 @Qualifier 注解指定的 bean 名称进行注入。
@Resource 注解
@Resource 注解是 JSR-250 定义的注解,该注解是按照 bean 名称进行注解的。但是使用了 @Resources 注解,不支持 @Primary 注解的功能。
@Inject 注解
@Inject 注解不建议使用,需要另外导入 javax.inject 包。 和 @Autowired 功能类似,但是没有 @Autoired 注解的 required 属性。