概述
本文介绍了IoC(控制反转)和DI(依赖注入)的概念以及如何在Spring框架中实现它们。
什么是控制反转?
控制反转是一种软件工程原理,它将对象或程序的一部分的控制转移到容器或框架。最常用于面向对象编程的上下文中。
与自定义代码调用库的传统编程相比,IoC 允许框架控制程序流程并调用自定义代码。为了实现这一点,该框架使用具有附加行为的抽象。如果您想添加自己的行为,则需要扩展框架的类或注入您自己的类。
这种架构的优点是:
将任务的执行和实现分开
不同实现之间的切换更容易
提高程序模块化程度
隔离组件或模拟它们的依赖关系并允许组件通过合约进行通信可以更轻松地测试您的程序。
IoC 可以通过策略设计模式、服务定位器模式、工厂模式和依赖注入(DI)等多种机制来实现。
什么是依赖注入?
依赖注入是一种可用于实现IoC 的模式,其中反转的控制是设置对象的依赖关系。
将对象连接到其他对象,或将对象“插入”到其他对象中,是由汇编器完成的,而不是由对象本身完成的。
以下是在传统编程中创建对象依赖关系的方法:
公共类商店{
私人物品物品;
公共商店() {
项目=新的ItemImpl1();
}
}
在上面的示例中,Store 类本身必须实例化Items 接口的实现。
使用DI,您可以重写此示例,而无需指定所需项目的实现。
公共类商店{
私人物品物品;
公共商店(项目项目){
this.item=项目;
}
}
在接下来的几节中,我们将了解如何通过元数据提供项目实现。
IoC 和DI 是简单的概念,但它们对系统的构建方式有巨大的影响,因此值得理解。
Spring IoC容器
IoC 容器是实现IoC 的框架的一个共同特征。
在Spring框架中,ApplicationContext接口代表一个IoC容器。 Spring 容器负责实例化、配置、组装和管理称为bean 的对象的生命周期。
Spring框架提供了ApplicationContext接口的多种实现。用于独立应用程序的ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext 以及用于Web 应用程序的WebApplicationContext。
为了组装bean,容器使用配置元数据。该元数据可以采用XML 配置或注释的形式。
手动实例化容器的一种方法如下:
ApplicationContext 上下文
=newClassPathXmlApplicationContext(\’applicationContext.xml\’);
在上面的示例中,您可以使用元数据设置item 属性,容器将读取此元数据并使用它在运行时组装bean。
在Spring 中,依赖注入可以通过构造函数、setter 或字段来完成。
基于构造函数的依赖注入
通过基于构造函数的依赖项注入,容器使用表示您要设置的依赖项的参数来调用构造函数。
Spring 按类型解析每个参数,并按属性名称和索引消除歧义。让我们看看使用注释的bean 及其依赖项的配置。
@作品
公共类AppConfig {
@豆子
公共项目item1() {
返回新的ItemImpl1();
}
@豆子
公共商店store() {
返回新商店(item1());
}
}
@Configuration 注释指示该类是bean 定义的源。它还可以添加到多个配置类中。
在方法上使用@Bean 注释来定义bean。如果不指定自定义名称,则bean 名称默认为方法名称。
对于默认的单例作用域bean,Spring 首先检查缓存的bean 实例是否已存在,只有在不存在时才创建一个新实例。当使用原型作用域时,容器为每个方法调用返回一个新的bean 实例。
创建bean 的另一种方法是使用XML 配置。
bean id=\’item1\’ class=\’org.baeldung.store.ItemImpl1\’ /
bean id=\’store\’ class=\’org.baeldung.store.Store\’
构造函数参数type=\’ItemImpl1\’ Index=\’0\’ name=\’item\’ ref=\’item1\’ /
/豆子
基于setter的依赖注入
对于基于setter 的DI,容器在实例化Bean 后通过调用不带参数的构造函数或调用不带参数的静态工厂方法来调用类的setter 方法。让我们使用注释创建此配置。
@豆子
公共商店store() {
商店商店=新商店();
store.setItem(item1());
退货商店;
}
您还可以使用XML 进行相同的bean 配置。
bean id=\’store\’ class=\’org.baeldung.store.Store\’
属性名称=\’item\’ ref=\’item1\’/
/豆子
您可以在同一个bean 中组合构造函数和setter 类型注入。 Spring 文档建议对必需的依赖项使用基于构造函数的注入,对可选依赖项使用基于设置器的注入。
基于字段的依赖注入
对于基于字段的DI,您可以使用@Autowired/@Resource 注解注入依赖项。
公共类商店{
@Autowired
私人物品物品;
}
在构造Store 对象时,如果没有用于注入Item 的构造函数或setter 方法,则容器会使用反射将Item 注入到Store 中。
您还可以使用XML 来实现此目的。
虽然这种方法看起来更简单、更清晰,但我们不建议使用这种方法,因为它有一些缺点:
此方法使用反射来注入依赖项,这比基于构造函数或基于setter 的注入更昂贵。
此方法允许您轻松添加多个依赖项。使用构造函数注入时,多个参数可能会导致类执行多项操作,可能违反单一责任原则。
自动装配依赖项
自动装配允许Spring 容器通过检查定义的bean 来自动解决协作bean 之间的依赖关系。
使用XML配置自动连接bean有四种模式:
no:默认值- 这意味着不使用自动装配,并且必须显式命名依赖项。
byName:按属性名称自动装配,因此Spring会查找与您需要设置的属性同名的bean。
byType:类似于按名称自动装配,仅基于属性的类型。这意味着Spring 将查找具有与您设置的类型相同的属性的bean。如果存在多个该类型的bean,框架将引发异常。
构造函数:基于构造函数参数的自动装配意味着Spring会搜索与构造函数参数相同类型的bean。
例如,让我们创建一个带有每种类型的依赖项的存储bean。
公共类AppConfig {
@豆子
公共项目item() {
返回新的ItemImpl1();
}
@Bean(autowire=Autowire.BY_TYPE)
公共商店store() {
返回新的Store();
}
}
请注意,自Spring 5.1 起,autowire 属性已被弃用。
您还可以使用@Autowired 注释按类型注入Bean。
公共类商店{
@Autowired
私人物品物品;
}
如果您有多个相同类型的bean,则可以使用@Qualifier 注释按名称引用这些bean。
公共类商店{
@Autowired
@限定符(\’项目1\’)
私人物品物品;
}
现在让我们使用XML 配置按类型自动装配bean。
bean id=\’store\’ class=\’org.baeldung.store.Store\’ autowire=\’byType\’ /bean
接下来,让我们通过XML 将名为item 的bean 按名称插入到Storebean 的item 属性中。
bean id=\’item\’ class=\’org.baeldung.store.ItemImpl1\’/
bean id=\’store\’ class=\’org.baeldung.store.Store\’ autowire=\’byName\’
/豆子
您还可以通过构造函数参数或设置器显式定义依赖项来覆盖自动装配。
惰性初始化的bean
默认情况下,容器在初始化期间创建并配置所有单例bean。为了避免这种情况,请在bean 配置中使用带有true 值的Lazy-init 属性。
bean id=\’item1\’ class=\’org.baeldung.store.ItemImpl1\’ Lazy-init=\’true\’ /
因此,item1bean仅在第一次请求时初始化,而不是在启动时初始化。这样做的优点是减少了初始化时间,但缺点是直到请求bean 时才检测到配置错误,这可能是在应用程序运行后数小时甚至数天。
文章转载自:Tetsu。
原文链接:https://www.cnblogs.com/xw-01/p/18263797
试用地址:英迈-JNPF 高速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流程引擎_软件架构
以上关于使用#Spring实现控制反转和依赖注入的相关内容摘自网络,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92311.html