DI 和 IOC 的关系
DI(依赖注入)和 IOC(控制反转)相关,但含义不同。
控制反转(IOC)是一种设计原则:组件不在自身代码中解析和管理依赖,而由外部容器或框架负责这些工作。组件因此可以替换依赖实现、复用,并在测试中注入替代依赖。
依赖注入(DI)是实现 IOC 的一种方式。注入器或容器创建并解析依赖,再将依赖提供给组件。组件声明所需依赖,而不负责获取或创建这些对象。依赖可以通过构造函数、属性或方法参数提供。
DI 框架和容器根据组件的声明和配置管理依赖关系并注入实例。这种分工降低了组件与依赖创建方式之间的耦合,但不自动保证架构可测试或可维护;依赖边界、作用域和配置仍需要明确设计。
IOC 基本概念
- 组件(Component):应用程序中可被容器管理的实体,可以是类、对象、服务或其他对象。
- 容器(Container):负责创建和管理组件。容器读取配置和应用程序代码,创建组件实例并解析依赖关系。
- 注册(Registration):在配置文件或代码中声明组件类型、名称、依赖关系等信息,使组件可由容器管理。
- 解析(Resolution):容器根据注册信息创建并返回请求的组件实例。解析可能创建新对象,也可能返回已有的单例对象。
- 依赖注入(Dependency Injection):容器将组件依赖的其他组件提供给目标组件。依赖可以通过构造函数、属性或方法参数注入。
- 生命周期管理(Lifecycle Management):IOC 框架可以在创建、初始化和销毁组件时执行相应逻辑,并触发生命周期事件。
- 作用域(Scope):定义组件实例的生命周期范围。例如,单例(Singleton)作用域的请求返回同一实例;原型(Prototype)作用域的每次请求创建新实例;有些框架还提供会话(Session)作用域。
- 配置(Configuration):组件注册信息、依赖关系和作用域设置等。配置可以通过 XML、注解或其他方式提供。
- AOP(Aspect-Oriented Programming):常与 IOC 一起使用的编程范式,用于分离横切关注点。切面可以在不修改组件业务代码的情况下处理日志记录、事务管理等跨组件功能。
DI 基本概念
依赖注入(Dependency Injection,DI)用于管理组件之间的依赖关系。实现 DI 框架通常涉及以下概念:
- 组件(Component):可被注入或管理的实体,可以是类、对象、服务或其他对象。
- 依赖(Dependency):组件需要使用的其他组件或服务。
- 注入器(Injector):创建和管理组件实例,并解析它们之间依赖关系的对象或容器。
- 注入点(Injection Point):组件接收依赖的位置,通常是构造函数、属性或方法参数。
- 注入策略(Injection Strategy):将依赖提供给组件的方式,包括构造函数注入、属性注入和方法注入。
- 生命周期管理(Lifecycle Management):DI 框架可以管理组件的创建、销毁和资源释放。
- 作用域(Scope):组件实例的生命周期范围,例如单例作用域和原型作用域。作用域决定组件的创建和销毁时机。
- 配置(Configuration):组件依赖关系、作用域设置和注入策略等信息。
- AOP(Aspect-Oriented Programming):可用于处理日志、事务管理等横切关注点。
IOC 的其他实现方式
依赖注入是 IOC 的常见实现方式之一。不同方式适用于不同的架构和开发环境,需要根据依赖可见性、生命周期管理需求和调用方式选择。
- 服务定位器模式(Service Locator Pattern):服务先注册到中心定位器,组件在需要时向定位器查找并获取服务。该方式可以实现 IOC,但服务获取操作会出现在组件中,依赖关系可能不如 DI 的构造函数参数直观。
- 工厂模式(Factory Pattern):工厂类根据调用返回所需实例,调用方不直接创建具体实现。这可以将对象创建移出业务类;对象生命周期通常仍需由调用方或额外机制管理。
- 模板方法模式(Template Method Pattern):抽象类定义算法或方法的执行顺序,子类按需重写其中步骤。该模式主要处理方法执行顺序,不负责通用的对象依赖解析。
- 策略模式(Strategy Pattern):将一组可替换算法分别封装,上下文通过策略接口调用具体算法。上下文依赖策略抽象,而非具体实现;策略选择仍需由调用方、工厂或容器完成。
