Spring中@Autowired、@Resource和@Inject注解的使用和区别
在使用Spring进行项目开发的时候,会大量使用到自动装配,那自动装配是什么呢?简单来说:Spring 利用依赖注入(DI)功能,完成SpringIOC容器中各个组件之间的依赖关系赋值管理。
下面介绍和总结可以在在Spring使用的三种自动注入的注解。首先回顾一下最初使用xml进行是如何进行注入的。
零、回顾:XML方式注入
使用 property 或者 constructor-arg 属性。
<!-- 配置需要被Spring管理的Bean(创建,创建后放在了Spring IOC容器里面)-->
<bean id="superMan" class="org.annotation.autowried.SuperMan">
<property name="car" ref="car"></property>
<!--<constructor-arg ref="car"/>-->
</bean>
<bean id="car" class="org.annotation.autowried.Car"/>
public class SuperMan {
private Car car;
/* private SuperMan(Car car){
this.car = car;
}*/
public void setCar(Car car) {
this.car = car;
}
}
public class Car {
private String brand = "喇嘛杀敌";
}
这样就能够将需要的组件注入到Spring中,并且进行组件中的依赖关系管理。回顾结束,通过这种方式来,配置比较繁琐,下面正式进入使用注解注入的主题。
@Autowired介绍
在Spring 2.5 引入了 @Autowired 注解!
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
从Autowired注解源码上看,可以使用在下面这些地方:
@Target(ElementType.CONSTRUCTOR) #构造函数
@Target(ElementType.METHOD) #方法
@Target(ElementType.PARAMETER) #方法参数
@Target(ElementType.FIELD) #字段、枚举的常量
@Target(ElementType.ANNOTATION_TYPE) #注解
还有一个value属性,默认是true。
简单总结:
1、@Autowired是Spring自带的注解,通过AutowiredAnnotationBeanPostProcessor 类实现的依赖注入
2、@Autowired可以作用在CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE
3、@Autowired默认是根据类型(byType )进行自动装配的
4、如果有多个类型一样的Bean候选者,需要指定按照名称(byName )进行装配,则需要配合@Qualifier。
指定名称后,如果Spring IOC容器中没有对应的组件bean抛出NoSuchBeanDefinitionException。也可以将@Autowired中required配置为false,如果配置为false之后,当没有找到相应bean的时候,系统不会抛异常
简单使用代码:
在字段属性上。
@Autowired
private HelloDao helloDao;
或者
private HelloDao helloDao;
public HelloDao getHelloDao() {
return helloDao;
}
@Autowired
public void setHelloDao(HelloDao helloDao) {
this.helloDao = helloDao;
}
或者
private HelloDao helloDao;
//@Autowired
public HelloServiceImpl(@Autowired HelloDao helloDao) {
this.helloDao = helloDao;
}
// 构造器注入也可不写@Autowired,也可以注入成功。
将@Autowired写在被注入的成员变量上,setter或者构造器上,就不用再xml文件中配置了。
如果有多个类型一样的Bean候选者,则默认根据设定的属性名称进行获取。如 HelloDao 在Spring中有 helloWorldDao 和 helloDao 两个Bean候选者。
@Autowired
private HelloDao helloDao;
首先根据类型获取,发现多个HelloDao,然后根据helloDao进行获取,如果要获取限定的其中一个候选者,结合@Qualifier进行注入。
@Autowired
@Qualifier("helloWorldDao")
private HelloDao helloDao;
注入名称为helloWorldDao 的Bean组件。@Qualifier("XXX") 中的 XX是 Bean 的名称,所以 @Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。
多个类型一样的Bean候选者,也可以@Primary进行使用,设置首选的组件,也就是默认优先使用哪一个。
注意:使用@Qualifier 时候,如何设置的指定名称的Bean不存在,则会抛出异常,如果防止抛出异常,可以使用:
@Qualifier("xxxxyyyy")
@Autowired(required = false)
private HelloDao helloDao;
在SpringBoot中也可以使用@Bean+@Autowired进行组件注入,将@Autowired加到参数上,其实也可以省略。
@Bean
public Person getPerson(@Autowired Car car){
return new Person();
}
// @Autowired 其实也可以省略
@Resource介绍
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
// 其他省略
}
从Resource注解源码上看,可以使用在下面这些地方:
@Target(ElementType.TYPE) #接口、类、枚举、注解
@Target(ElementType.FIELD) #字段、枚举的常量
@Target(ElementType.METHOD) #方法
name 指定注入指定名称的组件。
简单总结:
1、@Resource是JSR250规范的实现,在javax.annotation包下
2、@Resource可以作用TYPE、FIELD、METHOD上
3、@Resource是默认根据属性名称进行自动装配的,如果有多个类型一样的Bean候选者,则可以通过name进行指定进行注入
简单使用代码:
@Component
public class SuperMan {
@Resource
private Car car;
}
按照属性名称 car 注入容器中的组件。如果容器中BMW还有BYD两种类型组件。指定加入BMW。如下代码:
@Component
public class SuperMan {
@Resource(name = "BMW")
private Car car;
}
name 的作用类似 @Qualifier!
@Inject介绍
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
从Inject注解源码上看,可以使用在下面这些地方:
@Target(ElementType.CONSTRUCTOR) #构造函数
@Target(ElementType.METHOD) #方法
@Target(ElementType.FIELD) #字段、枚举的常量
简单总结:
1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject jar包 ,才能实现注入
2、@Inject可以作用CONSTRUCTOR、METHOD、FIELD上
3、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;
简单使用代码:
@Inject
private Car car;
指定加入BMW组件。
@Inject
@Named("BMW")
private Car car;
@Named 的作用类似 @Qualifier!
总结
1、@Autowired是Spring自带的,@Resource是JSR250规范实现的,@Inject是JSR330规范实现的
2、@Autowired、@Inject用法基本一样,不同的是@Inject没有一个request属性
3、@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
4、@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用,@Resource则通过name进行指定
Spring中@Autowired、@Resource和@Inject注解的使用和区别的更多相关文章
- Spring中@Autowired注解、@Resource注解的区别 (zz)
Spring中@Autowired注解.@Resource注解的区别 Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@ ...
- 【Spring注解驱动开发】你还不会使用@Resource和@Inject注解?那你就out了!!
写在前面 我在 冰河技术 微信公众号中发表的<[Spring注解驱动开发]使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?>一文中,介绍了如何使 ...
- Spring中的@Valid 和 @Validated注解你用对了吗
1.概述 本文我们将重点介绍Spring中 @Valid和@Validated注解的区别 . 验证用户输入是否正确是我们应用程序中的常见功能.Spring提供了@Valid和@Validated两个注 ...
- spring中bean的作用域属性singleton与prototype的区别
1.singleton 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会 ...
- Spring中Autowired注解,Resource注解和xml default-autowire工作方式异同
前面说到了关于在xml中有提供default-autowire的配置信息,从spring 2.5开始,spring又提供了一个Autowired以及javaEE中标准的Resource注释,都好像可以 ...
- Spring中 @Autowired注解与J2EE@Resource注解的区别
在开发中经常使用到@Autowired和@Resource进行装配. 不禁好奇这两个注解的差异在何处??? 相同点: @Resource的作用相当于@Autowired,均可标注在字段或属性的sett ...
- Spring中@Autowired注解、@Resource注解的区别
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...
- 转:Spring中@Autowired注解、@Resource注解的区别
Pay attention: When using these annotations, the object itself has to be created by Spring context. ...
- @Resource或者@Autowired作用/Spring中@Autowired注解、@Resource注解的区别
@Resource或者@Autowired作用不用写set get就能注入,当然,前提是你已经开启了注解功能. spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定 ...
随机推荐
- ASP.NET Core MVC 中的 Model 模型
ASP.NET Core MVC 中的 Model 我们希望最终从 Student 数据库表中查询特定的学生详细信息并显示在网页上,如下所示. MVC 中的模型包含一组表示数据的类和管理该数据的逻辑. ...
- C语言实现计算器,附源码,超简单!
#include<stdio.h> #include<math.h> void main() { calculator(); } double calculator() { / ...
- 【领会要领】web前端-轻量级框架应用(jQuery基础)
作者 | Jeskson 来源 | 达达前端小酒馆 jquery的安装和语法,jquery的多种选择器,dom操作和jquery事件. jQuery框架,简介,优势,安装,语法,jQuery选择器,i ...
- [LeetCode] 394. Decode String 解码字符串
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- 可以在shell脚本中使用哪些类型的变量?
在shell脚本,我们可以使用两种类型的变量: 系统定义变量 用户定义变量 系统变量是由系统系统自己创建的.这些变量通常由大写字母组成,可以通过“set”命令查看. 用户变量由系统用户来生成和定义,变 ...
- c# 在DataTable的第一列(指定列)的前面添加一列
c# 在DataTable的第一列(指定列)的前面添加一列 dt.Columns.Add("ID").SetOrdinal(0)
- laravel5.5框架中视图间如何共享数据?视图间共享数据的两种方法
laravel框架中视图间共享数据有两种,一种是用视图门面share()方法实现,另一种是用视图门面composer() 方法实现,那么,两种方法的实现究竟是怎样的呢?让我们来看一看接下来的文章内容. ...
- pandas的使用(6)离散化和合并
pandas的使用(6)离散化和合并
- Redmine添加插件
注意:插件的安装必须到Plugins对应的文件目录执行命令! Plugins Plugin list A full list of available Redmine plugins can be f ...
- 迅雷极速版开启强制升级迅雷X模式,网友出招
IT之家7月13日消息 近期,不少网友反馈,迅雷极速版已经开启强制用户升级到迅雷X的模式,而且不能关闭取消,并且会默认安装到C盘上 迅雷X是迅雷最新推出的下载客户端工具,使用Electron软件框架完 ...