@Resource和@Autowired都是Spring Framework中用于依靠注入的注解,但它们有几点不同:

  1. 来源不同:@Resource注解来自于J2EE标准中;而@Autowired注解是Spring结构供给的。

  2. 查找战略不同:@Resource注解默许依照称号进行匹配查找,假如找不到,则依照类型进行匹配。而@Autowired注解默许是依照类型进行匹配,假如出现多个类型共同的实例目标,则需求指定称号。

  3. 特点不同:@Resource注解没有特点称号,只要一个name特点,表明要注入的Bean称号。而@Autowired注解有两个重要特点:required和name,其间required特点表明是否有必要注入该特点,默以为true;name特点表明要注入的Bean称号。

1、用法层面剖析

首先,咱们创立一个接口UserService和两个完结类UserServiceImpl1UserServiceImpl2

public interface UserService {
    void save();
}
@Service
public class UserServiceImpl1 implements UserService {
    @Override
    public void save() {
        System.out.println("UserServiceImpl1 save");
    }
}
@Service
public class UserServiceImpl2 implements UserService {
    @Override
    public void save() {
        System.out.println("UserServiceImpl2 save");
    }
}

然后,咱们能够在需求运用UserService的当地进行依靠注入。

运用@Resource注解:

@Component
public class UserController {
    @Resource
    private UserService userService;
    // ...
}

运用@Autowired注解:

@Component
public class UserController {
    @Autowired(required = false)
    @Qualifier("userServiceImpl1")
    private UserService userService;
    // ...
}

上面的代码中,@Resource注解直接将UserService目标注入到userService特点中,而@Autowired注解需求结合@Qualifier注解来指定详细的Bean称号,并且经过required特点设置是否有必要注入该特点。留意,@Autowired注解也能够省略@Qualifier注解,此时会依照类型进行匹配查找对应的Bean。

2、概念层面剖析

再来剖析一下其间的道道~~

Spring Framework中的依靠注入完结原理是依据Java反射机制和JavaBean标准的。

  1. 经过反射机制实例化目标

Spring结构经过反射机制实例化需求注入的Bean目标,并将其存储到一个Map中,其间Key为Bean称号,Value为Bean实例目标。

  1. 经过JavaBean标准完结Bean特点注入

接下来,Spring会依据JavaBean标准(即特点名以及该特点的setter办法)查找需求注入的特点,并经过反射机制调用对应的setter办法进行特点注入。

  1. 依靠注入的查找战略

在依靠注入的进程中,Spring结构一般选用两种查找战略:

  • 依照类型查找:当需求注入的特点的类型与容器中的多个Bean的类型共同时,会依据不同的注解挑选不同的查找战略。比如运用@Autowired注解时,默许依照类型匹配查找对应的Bean。
  • 依照称号查找:当需求注入的特点的类型不仅有,或许需求注入的Bean称号与特点称号不共同时,能够运用@Qualifier注解指定要注入的Bean称号。
  1. 运用各种注解进行依靠注入

Spring结构供给了多种注解用于依靠注入,包括:

  • @Autowired:依照类型进行注入;
  • @Resource:依照称号进行注入;
  • @Value:注入简略类型或字符串类型的特点;
  • @Inject:JSR-330标准界说的注解,功能与@Autowired类似。

Spring Framework的依靠注入完结原理是依据Java反射机制和JavaBean标准的,并经过多种注解完结不同的依靠注入办法。

@Resource和@Autowired都是Spring的依靠注入注解,但它们有如下差异:

  1. 来源不同:@Resource是Java EE标准界说的注解,而@Autowired是Spring供给的注解。

  2. 特点不同:@Resource注解没有required特点,只要name特点,表明要注入的Bean称号;而@Autowired注解有required和name特点,其间required表明是否有必要注入该特点,默以为true;name表明要注入的Bean称号。

  3. 查找办法不同:@Resource注解默许是依据byName的办法进行查找,假如找不到则依照byType进行查找;而@Autowired默许是依据byType办法进行查找。

  4. 兼容性不同:@Resource注解能够与JSR-330的@Inject注解调配运用;而@Autowired注解只能与Spring组件一同运用。

  5. 运用场景不同:@Resource注解首要运用于Java EE环境,而@Autowired注解则是在Spring结构中运用最广泛的依靠注入注解之一,能够适用于不同的运用场景。

下面别离介绍@Resource和@Autowired注解的优缺陷:

@Resource优点:

  1. 简略易用,在类中运用非常方便。

  2. 能够和@Inject注解一同运用。

  3. 支撑指定Bean称号,能够更精确地进行依靠注入。

@Resource缺陷:

  1. Spring结构对@Resource注解的支撑不如@Autowired丰富。

  2. 仅支撑byName和byType两种注入办法,比@Autowired的支撑更为有限。

@Autowired优点:

  1. 支撑复杂的依靠注入装备,能够经过多种办法进行依靠注入。

  2. Spring结构对@Autowired注解的支撑非常丰富,是Spring中运用最广泛的注解之一。

  3. 能够指定是否有必要注入该特点,也能够指定Bean称号进行注入。

  4. 除了在类中运用之外,还能够在结构办法、Setter办法及任何标记了@Bean的办法中运用@Autowired注解。

@Autowired缺陷:

  1. 装备较为繁琐,需求指定required和name特点等。

  2. 需求遵循Spring的主动扫描机制,只要标记了@Component、@Service、@Controller和@Repository等注解的类才会被Spring容器进行办理。

关于依靠注入的原理,能够简略地归纳为以下三个步骤:

  1. 在运用程序启动时,Spring容器担任创立和办理一切的Bean实例目标。

  2. 在需求运用某个Bean的时候,Spring容器会经过反射机制将该Bean注入到需求运用的类或目标中。

  3. 在Bean注入的进程中,Spring容器会依据不同的注解(如@Resource、@Autowired)选用不同的依靠注入办法,完结依靠注入的进程。

@Resouce和@Autowired都是Spring供给的依靠注入注解,各有优缺陷。在实践开发中,能够依据详细的运用场景挑选适宜的注解进行运用。

2、源码层面剖析

在Spring Framework源码层面,@Resource和@Autowired注解的完结类别离为javax.annotation.Resource和org.springframework.beans.factory.annotation.Autowired。下面咱们来看一下它们的详细完结。

@Resource注解的完结原理:

  1. 假如@Resource注解的name特点不为空,则Spring容器依据该特点值查找需求注入的Bean实例目标;假如name特点为空,则默许运用字段名作为Bean称号进行查找。

  2. Spring容器会先依据byName注入办法进行查找,假如没有找到对应的Bean实例,则依据byType办法进行查找。

  3. 假如找到了对应的Bean实例,则运用反射机制将该Bean实例注入到需求运用该实例的类或目标中。

  4. 假如没有找到对应的Bean实例,则抛出NoSuchBeanDefinitionException反常。

代码示例:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
    String name() default "";
    Class<?> type() default java.lang.Object.class;
    boolean shareable() default true;
}

@Autowired注解的完结原理:

  1. Spring容器会依据AutowiredAnnotationBeanPostProcessor类和AutowiredAnnotationBeanPostProcessor类的派生类进行处理,将运用@Autowired注解标记的一切特点注入到需求运用的类或目标中。

  2. 关于AutowiredAnnotationBeanPostProcessor,其完结了BeanPostProcessor接口,在Bean实例化、初始化的进程中会阻拦@Autowired注解。

  3. 当Spring容器遇到@Autowired注解时,会主动调用AutowiredAnnotationBeanPostProcessor类的postProcessPropertyValues办法,该办法会依据不同的注解特点值进行不同的依靠注入处理。

  4. 在处理@Autowired注解时,Spring容器默许运用byType的办法进行查找,假如存在多个匹配类型的Bean,则依据类名进行匹配;假如仍然无法确认注入哪个Bean,则抛出NoSuchBeanDefinitionException反常。

代码示例:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
    String value() default "";
}

无论是@Resource注解仍是@Autowired注解,在Spring Framework源码完结上都是经过反射机制和BeanPostProcessor接口完结依靠注入的。在实践开发中,咱们能够研讨对应的源码完结,深化了解它们的原理,然后更好地运用这些依靠注入注解。