Skip to content

@Autowired@Resource 的区别

🏷️ MyBatis Spring Boot

  1. @Resource 默认是 按照名称 来装配注入的;

    xml
    <bean id="daoConfigDev" class="liujiajia.me.learning.mybatis.DaoConfig">
        <property name="username" value="jiajia" />
        <property name="password" value="jiajiaspassword"/>
    </bean>
    <bean id="daoConfigRelease" class="liujiajia.me.learning.mybatis.DaoConfig">
        <property name="username" value="admin" />
        <property name="password" value="adminspassword"/>
    </bean>
    java
    @Resource
    DaoConfig daoConfigDev;
    
    @Resource
    DaoConfig daoConfigRelease;

    名称可以通过 name 属性进行指定,如果没有指定 name 属性,当注解写在字段上时,默认取 字段名 ,按照名称查找,如果注解写在 setter 方法上默认取 属性名 进行装配;

    java
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
    * Created by liujiajia on 2019/1/24.
    */
    @Component
    public class Configs {
        // 会优先使用 name 属性指定的名称来装配
        @Resource(name = "daoConfigRelease")
        private DaoConfig daoConfig;
        @Resource
        private DaoConfig daoConfigDev;
        @Resource
        private DaoConfig daoConfigRelease;
    
        // getter setter ...
    }
    java
    @Resource(name = "daoConfigRelease")
    public void setDaoConfig(DaoConfig daoConfig) {
        this.daoConfig = daoConfig;
    }
    @Resource
    public void setDaoConfigDev(DaoConfig daoConfigDev) {
        this.daoConfigDev = daoConfigDev;
    }
    @Resource
    public void setDaoConfigRelease(DaoConfig daoConfigRelease) {
        this.daoConfigRelease = daoConfigRelease;
    }

    只有当找不到与名称匹配的 bean 才会按照类型来装配注入;

    如果有多个同类型的 bean 则启动时会发生 NoUniqueBeanDefinitionException 异常:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'liujiajia.me.learning.mybatis.DaoConfig' available: expected single matching bean but found 2: daoConfigDev,daoConfigRelease

  2. @Autowired 默认是 按照类型 装配注入的;

    java
    @Autowired
    private DaoConfig daoConfig;

    如果想按照名称来装配注入,则需要结合 @Qualifier 一起使用;

    java
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
    * Created by liujiajia on 2019/1/24.
    */
    @Component
    public class Configs {
        // 会优先使用 name 属性指定的名称来装配
        @Autowired
        @Qualifier("daoConfigRelease")
        private DaoConfig daoConfig;
        @Autowired
        @Qualifier("daoConfigDev")
        private DaoConfig daoConfigDev;
        @Autowired
        @Qualifier("daoConfigRelease")
        private DaoConfig daoConfigRelease;
    
        public DaoConfig getDaoConfig() {
            return daoConfig;
        }
    
        // getter setter ...
    }

    否则启动时会报错。

    Field daoConfig in liujiajia.me.learning.mybatis.Configs required a single bean, but 2 were found:
    - daoConfigDev: defined in class path resource [applicationContext.xml]
    - daoConfigRelease: defined in class path resource [applicationContext.xml]

  3. @Resource 注解是由 JDK 提供,而 @Autowired 是由 Spring 提供;

  4. @Resource@Autowired 都可以书写标注在字段或者该字段的 setter 方法之上;

    java
    @Autowired
    private DaoConfig daoConfig;
    
    @Resource
    private DaoConfig daoConfig;
    java
    @Autowired
    public void setDaoConfig(DaoConfig daoConfig) {
        this.daoConfig = daoConfig;
    }
    
    @Resource
    public void setDaoConfig(DaoConfig daoConfig) {
        this.daoConfig = daoConfig;
    }

详细的解释可以参考 @Autowired 和@Resource 的区别是什么?@Resource 和@Autowire 的区别