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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 6,852评论 2 22
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,665评论 19 139
  • 转 Spring****基于 Annotation 的简单介绍 2011年03月29日 15:07:00 阅读数:...
    fd649cf896c0阅读 380评论 1 0
  • 文章作者:Tyan博客:noahsnail.com | CSDN | 简书 3.9 Annotation-base...
    SnailTyan阅读 1,280评论 0 3
  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 7,047评论 4 21

友情链接更多精彩内容