问题一:使用@Autowired 时 ide会出现警告,无法注入,详细提示如下
如果将@Autowired 换为 @Resource,提示消除
问题二:Autowired Resource 区别联系
来源不同:
@Autowired 是Spring框架提供的注解。
@Resource 是Java标准(JSR-250)的一部分,由javax.annotation包提供。
注入机制不同:
@Autowired 默认按类型(by-type)进行自动装配,如果找到多个相同类型的bean,则会根据名称(by-name)进行匹配。
@Resource 默认按名称(by-name)进行装配,如果找不到与名称匹配的bean,则回退到按类型(by-type)装配。
IDE和编译器支持:
有些IDE对Java标准注解(如 @Resource)的支持可能比对框架特定注解(如 @Autowired)更好,特别是在一些静态分析或代码检查方面。
问题三:Field injection is not recommended 究竟是什么
不建议使用字段注入,该问题的本质是Spring官方推荐使用构造器注入,IDEA作为一款智能化的IDE,针对该项进行了检测并给以提示。
问题四:三种依赖注入的方式
1. 构造器注入(Constructor Injection)
优点:
不可变性:通过构造器注入的依赖通常被声明为 final,确保对象一旦创建后依赖不会被修改。
强制依赖:构造器参数是必需的,可以确保依赖在对象创建时就被提供,避免 null 引用。
易于测试:在单元测试中,可以直接通过构造器传入模拟对象,便于编写测试用例。
清晰性:依赖关系在构造器中一目了然,便于理解和维护。
缺点:
构造器参数过多:当依赖项较多时,构造器参数会变得冗长,影响可读性。
循环依赖问题:构造器注入无法处理循环依赖,容易在初始化时抛出异常。
public class Service {
private final Repository repository;
public Service(Repository repository) {
this.repository = repository;
}
}
2. Setter 注入(Setter Injection)
优点:
灵活性:可以在对象创建后动态地设置依赖项,适用于可选依赖。
易于修改:依赖项可以在运行时通过 setter 方法重新设置。
解决循环依赖:Setter 注入可以处理某些循环依赖的情况。
缺点:
可变性:依赖项可以在任何时候被修改,破坏了对象的不变性。
依赖不明确:依赖关系不如构造器注入那样明显,可能导致遗漏依赖项。
运行时错误:如果忘记调用 setter 方法,可能导致 NullPointerException。
public class Service {
private Repository repository;
public void setRepository(Repository repository) {
this.repository = repository;
}
}
3. 字段注入(Field Injection)
优点:
简洁性:代码最简洁,只需在字段上添加注解(如 @Autowired)。
开发效率:减少了样板代码,快速实现依赖注入。
缺点:
不可变性差:字段通常不能声明为 final,破坏了对象的不变性。
难以测试:在单元测试中难以手动注入依赖,通常需要依赖容器或反射。
依赖不透明:依赖关系不明确,增加了代码维护的难度。
容器依赖:字段注入强依赖于 DI 容器,使得类在脱离容器时难以使用。
public class Service {
@Autowired
private Repository repository;
}
在实际开发中,构造器注入是最推荐的方式,因为它提供了更好的不可变性和明确的依赖关系,而字段注入应尽量避免使用。