做一个积极的人
编码、改bug、提升自己
我有一个乐园,面向编程,春暖花开!
![2bc59e1ab2b31f2c5cd307efeb1ad99d.png](https://i-blog.csdnimg.cn/blog_migrate/327fb796574fcc2e6162690341217826.jpeg)
在使用Spring进行项目开发的时候,会大量使用到自动装配,那自动装配是什么呢?简单来说:Spring 利用依赖注入(DI)功能,完成SpringIOC容器中各个组件之间的依赖关系赋值管理。
下面介绍和总结可以在在Spring使用的三种自动注入的注解。首先回顾一下最初使用xml进行是如何进行注入的。
零、回顾:XML方式注入
使用 property 或者 constructor-arg 属性。
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)@Documentedpublic @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的时候,系统不会抛异常
简单使用代码:
在字段属性上。
@Autowiredprivate HelloDao helloDao;
或者
private HelloDao helloDao;public HelloDao getHelloDao() { return helloDao;}@Autowiredpublic void setHelloDao(HelloDao helloDao) { this.helloDao = helloDao;}
或者
private HelloDao helloDao;//@Autowiredpublic HelloServiceImpl(@Autowired HelloDao helloDao) { this.helloDao = helloDao;}// 构造器注入也可不写@Autowired,也可以注入成功。
将@Autowired写在被注入的成员变量上,setter或者构造器上,就不用再xml文件中配置了。
如果有多个类型一样的Bean候选者,则默认根据设定的属性名称进行获取。如 HelloDao 在Spring中有 helloWorldDao 和 helloDao 两个Bean候选者。
@Autowiredprivate 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加到参数上,其实也可以省略。
@Beanpublic 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进行指定进行注入
简单使用代码:
@Componentpublic class SuperMan { @Resource private Car car;}
按照属性名称 car 注入容器中的组件。如果容器中BMW还有BYD两种类型组件。指定加入BMW。如下代码:
@Componentpublic class SuperMan { @Resource(name = "BMW") private Car car;}
name 的作用类似 @Qualifier!
三、@Inject介绍
@Target({ METHOD, CONSTRUCTOR, FIELD })@Retention(RUNTIME)@Documentedpublic @interface Inject {}
从Resource注解源码上看,可以使用在下面这些地方:
@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;
简单使用代码:
@Injectprivate 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进行指定
![d1c362322a12286fb32c9b58770319e9.gif](https://i-blog.csdnimg.cn/blog_migrate/b95e0fbbc59260bec7413a3557595cee.gif)