当我们在属性上使用@Autowired的时候,IDEA会曝黄色的警告,如下图所示:
你如果问老员工应该怎么办时,一般会让你换成@Resource注解,问其原因,可能大部分人都不太讲的清楚。
要弄清楚,就要先了解@Resource和@Autowired注解的身世。
@Resource注解,由2006年5月的 JSR 250(Java) 发布 。
@Resource注解的官方介绍:
1、标记了应用程序需要的资源。
2、可以应用于应用程序组件类或者组件类的字段或方法。
3、当应用于字段或方法时,容器将在组件初始化时将所请求资源的实例注入到应用程序组件中。
3、如果应用于组件类,则注释声明应用程序将在运行时查找的资源。
@Autowired注解,由2007年11月19日的 Spring2.5 发布。
@Autowired注解的官方介绍:
1、将构造函数、字段、设置方法或者配置方法标记为由 Spring 的依赖注入工具自动装配。
@Autowired注解IDEA为什么会曝黄色的警告?
警告的内容为:field injection is not recommended(不推荐使用Field注入),那应该推荐使用什么方式注入呢?
我们先来看下,常见的三种依赖注入方式:
1. Filed注入
2. Setter注入
3. 构造方法注入
属性方法(Filed)注入,此方式是使用最多的,因为这种方式使用起来非常简单,代码也非常的简洁。
@Controller
public class HelloController {@Autowiredprivate CourseService courseService;
}
普通方法(Setter)注入,就是先写Setter函数,然后在使用到的地方直接调用。
@Controller
public class HelloController {private CourseService courseService;@Autowiredpublic void setCourseService(CourseService courseService) {this.courseService = courseService;}
}
构造方法(Constructor)注入,就是使用构造函数的方法实现。
@Controller
public class HelloController {private final CourseService courseService;@Autowiredpublic HelloController(CourseService courseService) {this.courseService = courseService;}
}
Filed注入,声明不了常量的属性,因为 final 的字段必须在类实例化时去实例化。
Filed注入,在类中很容易有很多依赖。
Filed注入,违反单一原则,当有多个依赖时,不容易看出依赖关系,容易循环依赖。
Filed注入,无法独立于容器之外实例化。
——————————————————————————————————————————————
Setter注入,实现可选依赖。
Setter注入,可以将依赖项部分注入。
Setter注入,可以解决循环依赖。
Setter注入,自己开发的模块推荐使用。
Setter注入,可变的。
——————————————————————————————————————————————
Constructor注入,实现强制依赖。
Constructor注入,只能将依赖项全部注入。
Constructor注入,为创建实例的第一选项。
Constructor注入,可以解决循环依赖。
Constructor注入,是Spring框架极力倡导使用的方式。
Constructor注入,不变的。
——————————————————————————————————————————————
所以,警告的内容为:field injection is not recommended(不推荐使用Field注入),那应该推荐使用什么方式注入呢?
答案是:在Spring框架里面,肯定是极力推荐 Constructor注入的方式。
由于此处使用的是 @Autowired 注解 Filed 注入,为了方便且不报错,所以把 @Autowired 注解改成 @Resource 注解 Filed 注入即可。
区别1:
身世不同:
区别2:
注入方式不同:
区别3:
依赖查找顺序不同:
区别4:
支持的参数不同:
@Resource 倾向于确定性的单一资源。
@Autowired 为类型去匹配符合此类型的所有资源。
如集合注入,建议使用 @Autowired。
@Autowired 的推荐用法:
1)使用构造函数注入或者 lombok 的 @RequiredArgsConstructor+private final。
2)使用set注入或者 lombok 的 @Setter。