@Resource和@Autowired都是Spring Framework中用于依靠注入的注解,但它们有几点不同:
来源不同:@Resource注解来自于J2EE标准中;而@Autowired注解是Spring结构供给的。
查找战略不同:@Resource注解默许依照称号进行匹配查找,假如找不到,则依照类型进行匹配。而@Autowired注解默许是依照类型进行匹配,假如出现多个类型共同的实例目标,则需求指定称号。
特点不同:@Resource注解没有特点称号,只要一个name特点,表明要注入的Bean称号。而@Autowired注解有两个重要特点:required和name,其间required特点表明是否有必要注入该特点,默以为true;name特点表明要注入的Bean称号。
1、用法层面剖析
首先,咱们创立一个接口UserService
和两个完结类UserServiceImpl1
和UserServiceImpl2
。
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标准的。
- 经过反射机制实例化目标
Spring结构经过反射机制实例化需求注入的Bean目标,并将其存储到一个Map中,其间Key为Bean称号,Value为Bean实例目标。
- 经过JavaBean标准完结Bean特点注入
接下来,Spring会依据JavaBean标准(即特点名以及该特点的setter办法)查找需求注入的特点,并经过反射机制调用对应的setter办法进行特点注入。
- 依靠注入的查找战略
在依靠注入的进程中,Spring结构一般选用两种查找战略:
- 依照类型查找:当需求注入的特点的类型与容器中的多个Bean的类型共同时,会依据不同的注解挑选不同的查找战略。比如运用@Autowired注解时,默许依照类型匹配查找对应的Bean。
- 依照称号查找:当需求注入的特点的类型不仅有,或许需求注入的Bean称号与特点称号不共同时,能够运用@Qualifier注解指定要注入的Bean称号。
- 运用各种注解进行依靠注入
Spring结构供给了多种注解用于依靠注入,包括:
- @Autowired:依照类型进行注入;
- @Resource:依照称号进行注入;
- @Value:注入简略类型或字符串类型的特点;
- @Inject:JSR-330标准界说的注解,功能与@Autowired类似。
Spring Framework的依靠注入完结原理是依据Java反射机制和JavaBean标准的,并经过多种注解完结不同的依靠注入办法。
@Resource和@Autowired都是Spring的依靠注入注解,但它们有如下差异:
-
来源不同:@Resource是Java EE标准界说的注解,而@Autowired是Spring供给的注解。
-
特点不同:@Resource注解没有required特点,只要name特点,表明要注入的Bean称号;而@Autowired注解有required和name特点,其间required表明是否有必要注入该特点,默以为true;name表明要注入的Bean称号。
-
查找办法不同:@Resource注解默许是依据byName的办法进行查找,假如找不到则依照byType进行查找;而@Autowired默许是依据byType办法进行查找。
-
兼容性不同:@Resource注解能够与JSR-330的@Inject注解调配运用;而@Autowired注解只能与Spring组件一同运用。
-
运用场景不同:@Resource注解首要运用于Java EE环境,而@Autowired注解则是在Spring结构中运用最广泛的依靠注入注解之一,能够适用于不同的运用场景。
下面别离介绍@Resource和@Autowired注解的优缺陷:
@Resource优点:
-
简略易用,在类中运用非常方便。
-
能够和@Inject注解一同运用。
-
支撑指定Bean称号,能够更精确地进行依靠注入。
@Resource缺陷:
-
Spring结构对@Resource注解的支撑不如@Autowired丰富。
-
仅支撑byName和byType两种注入办法,比@Autowired的支撑更为有限。
@Autowired优点:
-
支撑复杂的依靠注入装备,能够经过多种办法进行依靠注入。
-
Spring结构对@Autowired注解的支撑非常丰富,是Spring中运用最广泛的注解之一。
-
能够指定是否有必要注入该特点,也能够指定Bean称号进行注入。
-
除了在类中运用之外,还能够在结构办法、Setter办法及任何标记了@Bean的办法中运用@Autowired注解。
@Autowired缺陷:
-
装备较为繁琐,需求指定required和name特点等。
-
需求遵循Spring的主动扫描机制,只要标记了@Component、@Service、@Controller和@Repository等注解的类才会被Spring容器进行办理。
关于依靠注入的原理,能够简略地归纳为以下三个步骤:
-
在运用程序启动时,Spring容器担任创立和办理一切的Bean实例目标。
-
在需求运用某个Bean的时候,Spring容器会经过反射机制将该Bean注入到需求运用的类或目标中。
-
在Bean注入的进程中,Spring容器会依据不同的注解(如@Resource、@Autowired)选用不同的依靠注入办法,完结依靠注入的进程。
@Resouce和@Autowired都是Spring供给的依靠注入注解,各有优缺陷。在实践开发中,能够依据详细的运用场景挑选适宜的注解进行运用。
2、源码层面剖析
在Spring Framework源码层面,@Resource和@Autowired注解的完结类别离为javax.annotation.Resource和org.springframework.beans.factory.annotation.Autowired。下面咱们来看一下它们的详细完结。
@Resource注解的完结原理:
-
假如@Resource注解的name特点不为空,则Spring容器依据该特点值查找需求注入的Bean实例目标;假如name特点为空,则默许运用字段名作为Bean称号进行查找。
-
Spring容器会先依据byName注入办法进行查找,假如没有找到对应的Bean实例,则依据byType办法进行查找。
-
假如找到了对应的Bean实例,则运用反射机制将该Bean实例注入到需求运用该实例的类或目标中。
-
假如没有找到对应的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注解的完结原理:
-
Spring容器会依据AutowiredAnnotationBeanPostProcessor类和AutowiredAnnotationBeanPostProcessor类的派生类进行处理,将运用@Autowired注解标记的一切特点注入到需求运用的类或目标中。
-
关于AutowiredAnnotationBeanPostProcessor,其完结了BeanPostProcessor接口,在Bean实例化、初始化的进程中会阻拦@Autowired注解。
-
当Spring容器遇到@Autowired注解时,会主动调用AutowiredAnnotationBeanPostProcessor类的postProcessPropertyValues办法,该办法会依据不同的注解特点值进行不同的依靠注入处理。
-
在处理@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接口完结依靠注入的。在实践开发中,咱们能够研讨对应的源码完结,深化了解它们的原理,然后更好地运用这些依靠注入注解。