海淀网站建设wzjs51爱你社区
海淀网站建设wzjs51,爱你社区,什么网站做贸易好,建湖专业做网站目录 前言
说明
依赖注入的类型
2.1 基于构造器的依赖注入
2.2 基于 Setter 的依赖注入
2.3 基于属性的依赖注入
基于字段的依赖注入缺陷
3.1 不允许声明不可变域
3.2 容易违反单一职责设计原则
3.3 与依赖注入容器紧密耦合
3.4 隐藏依赖关系
总结
参考文档 前言
…
目录 前言
说明
依赖注入的类型
2.1 基于构造器的依赖注入
2.2 基于 Setter 的依赖注入
2.3 基于属性的依赖注入
基于字段的依赖注入缺陷
3.1 不允许声明不可变域
3.2 容易违反单一职责设计原则
3.3 与依赖注入容器紧密耦合
3.4 隐藏依赖关系
总结
参考文档 前言
Spring 官方已不推荐使用 Autowired 字段/属性注入 bean一些大公司的新项目也明令禁止使用了。
说明
最近公司升级框架由原来的 spring framework 3.0 升级到 5.0然后写代码的时候突然发现 idea 在属性注入的 Autowired 注解上给出警告提示就像下面这样的也是挺懵逼的毕竟这么写也很多年了。 Field injection is not recommended 查阅了相关文档了解了一下原来这个提示是 spring framework 4.0 以后开始出现的spring 4.0 开始就不推荐使用属性注入改为推荐构造器注入和 setter 注入。
下面将展示了 spring 框架可以使用的不同类型的依赖注入以及每种依赖注入的适用情况。
依赖注入的类型
尽管针对 spring framework 5.1.3 的文档只定义了两种主要的依赖注入类型但实际上有三种
基于构造器的依赖注入基于 setter 的依赖注入基于字段的依赖注入
其中基于字段的依赖注入被广泛使用但是 idea 或者其他静态代码分析工具会给出提示信息不推荐使用。
甚至可以在一些 Spring 官方指南中看到这种注入方法 2.1 基于构造器的依赖注入
在基于构造函数的依赖注入中类构造函数被标注为 Autowired并包含了许多与要注入的对象相关的参数。 Component
public class ConstructorBasedInjection {private final InjectedBean injectedBean;Autowired public ConstructorBasedInjection(InjectedBean injectedBean) { this.injectedBean injectedBean; }
}然后在spring官方文档中Autowired 注解也是可以省去的。 public class SimpleMovieLister {// the SimpleMovieLister has a dependency on a MovieFinderprivate MovieFinder movieFinder;// a constructor so that the Spring container can inject a MovieFinderpublic SimpleMovieLister(MovieFinder movieFinder) {this.movieFinder movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...
}基于构造函数注入的主要优点是可以将需要注入的字段声明为 final 使得它们会在类实例化期间被初始化这对于所需的依赖项很方便。
2.2 基于 Setter 的依赖注入
在基于 setter 的依赖注入中setter 方法被标注为 Autowired。一旦使用无参数构造函数或无参数静态工厂方法实例化 Bean为了注入 Bean 的依赖项Spring 容器将调用这些 setter 方法。 Component
public class SetterBasedInjection {private InjectedBean injectedBean;Autowiredpublic void setInjectedBean(InjectedBean injectedBean) {this.injectedBean injectedBean;}
}和基于构造器的依赖注入一样在官方文档中基于 Setter 的依赖注入中的 Autowired 也可以省去。 public class SimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivate MovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublic void setMovieFinder(MovieFinder movieFinder) {this.movieFinder movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...
}2.3 基于属性的依赖注入
在基于属性的依赖注入中字段/属性被标注为 Autowired。一旦类被实例化Spring 容器将设置这些字段。 Component
public class FieldBasedInjection {Autowiredprivate InjectedBean injectedBean;
}正如所看到的这是依赖注入最干净的方法因为它避免了添加样板代码并且不需要声明类的构造函数。代码看起来很干净简洁但是正如代码检查器已经向我们暗示的那样这种方法有一些缺点。
基于字段的依赖注入缺陷
3.1 不允许声明不可变域
基于字段的依赖注入在声明为 final/immutable 的字段上不起作用因为这些字段必须在类实例化时实例化。声明不可变依赖项的唯一方法是使用基于构造器的依赖注入。
3.2 容易违反单一职责设计原则
在面向对象的编程中五大设计原则SOLID被广泛应用国内一般为六大设计原则用以提高代码的重用性可读性可靠性和可维护性。
S 在 SOLID 中代表单一职责原则即一个类应该只负责一项职责这个类提供的所有服务都应该只为它负责的职责服务。
使用基于字段的依赖注入高频使用的类随着时间的推移我们会在类中逐渐添加越来越多的依赖项我们用着很爽很容易忽略类中的依赖已经太多了。但是如果使用基于构造函数的依赖注入随着越来越多的依赖项被添加到类中构造函数会变得越来越大我们一眼就可以察觉到哪里不对劲。
有一个有超过10个参数的构造函数是一个明显的信号表明类已经转变一个大而全的功能合集需要将类分割成更小、更容易维护的块。
因此尽管属性注入并不是破坏单一责任原则的直接原因但它隐藏了信号使我们很容易忽略这些信号。spring系列技术文章Spring基础 - Spring 常用七大类注解 | 素文宅 (yoodb.com)
3.3 与依赖注入容器紧密耦合
使用基于字段的依赖注入的主要原因是为了避免 getter 和 setter 的样板代码或为类创建构造函数。最后这意味着设置这些字段的唯一方法是通过Spring容器实例化类并使用反射注入它们否则字段将保持 null。
依赖注入设计模式将类依赖项的创建与类本身分离开来并将此责任转移到类注入容器从而允许程序设计解耦并遵循单一职责和依赖项倒置原则(同样可靠)。因此通过自动装配autowiring字段来实现的类的解耦最终会因为再次与类注入容器(在本例中是 Spring)耦合而丢失从而使类在Spring容器之外变得无用。
这意味着如果您想在应用程序容器之外使用您的类例如用于单元测试您将被迫使用 Spring 容器来实例化您的类因为没有其他可能的方法(除了反射)来设置自动装配字段。
3.4 隐藏依赖关系
在使用依赖注入时受影响的类应该使用公共接口清楚地公开这些依赖项方法是在构造函数中公开所需的依赖项或者使用方法(setter)公开可选的依赖项。当使用基于字段的依赖注入时实质上是将这些依赖对外隐藏了。
总结
我们已经看到基于字段的注入应该尽可能地避免因为它有许多缺点无论它看起来多么优雅。推荐的方法是使用基于构造函数和基于setter的依赖注入。对于必需的依赖建议使用基于构造函数的注入设置它们为不可变的并防止它们为 null。对于可选的依赖项建议使用基于 setter 的注入。
参考文档
Field injection is not recommended – Spring IOC by Marc Nuri
spring官方文档 1.4. Dependencies
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/88419.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!