@Autowired和@Resource用法比较

一、@Autowired和@Resource比较

1、相同点

两个注解都是做bean的注入时使用,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。

2、不同点

  1. 基因不同:@Autowired是由org.springframework.beans.factory.annotation.Autowired提供,换句话说就是由Spring提供;@Resource是由javax.annotation.Resource提供,即J2EE提供,需要JDK1.6及以上。
  2. @Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

二、@Resource简介

1、属性

@Resource默认按照ByName自动注入。

@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

2、装配顺序

  • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  • 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  • 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

三、Demo示例

1、代码实现

dao层,用于测试注解@Autowired采用ByType方式:

package com.example.demo.dao;

import org.springframework.stereotype.Repository;

@Repository
public class TestAutoWiredDao {

    public void autowiredByType(){
        System.out.println("Autowired采用ByType匹配");
    }
}
package com.example.demo.pojo;

public class TestAutowiredPojo {

    public void autowiredByName(){
        System.out.println("Autowired采用ByName匹配");
    }
}
package com.example.demo.pojo;

public class TestResourcePojo {

    public void resourceByName() {
        System.out.println("Resource采用ByName匹配");
    }

    public void resourceByType() {
        System.out.println("Resource采用ByType匹配");
    }
}

Config配置:

package com.example.demo.config;

import com.example.demo.pojo.TestAutowiredPojo;
import com.example.demo.pojo.TestResourcePojo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

  @Bean
  public TestResourcePojo testResourcePojo(){
      return new TestResourcePojo();
  }

  @Bean
  public TestAutowiredPojo testAutowiredPojo(){
    return new TestAutowiredPojo();
  }
}

调用:

package com.example.demo.service;

import com.example.demo.dao.TestAutoWiredDao;
import com.example.demo.pojo.TestAutowiredPojo;
import com.example.demo.pojo.TestResourcePojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class TestService {

    @Autowired
    private TestAutoWiredDao testAutoWiredDao;

    @Autowired
    @Qualifier("testAutowiredPojo")
    private TestAutowiredPojo testAutowiredPojo;

    @Resource(name = "testResourcePojo")
    private TestResourcePojo testResourcePojoOne;

    @Resource(type = TestResourcePojo.class)
    private TestResourcePojo testResourcePojoTwo;


    public void testAnnotate(){
        testAutoWiredDao.autowiredByType();
        testAutowiredPojo.autowiredByName();
        testResourcePojoOne.resourceByName();
        testResourcePojoTwo.resourceByType();
    }
}
package com.example.demo.controller;

import com.example.demo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    public TestService testService;

    @RequestMapping("testAnnotate")
    public void testAnnotate(){
        testService.testAnnotate();
    }
}

2、代码结构

@Autowired和@Resource用法比较插图

3、运行结果

Autowired采用ByType匹配
Autowired采用ByName匹配
Resource采用ByName匹配
Resource采用ByType匹配

发表评论