@Autowired 和 @Resource 注解

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 注入成功

将 @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 属性。

你可能感兴趣的:(@Autowired 和 @Resource 注解)