以下是一个使用Java手动实现依赖注入(DI)的简单示例:
// 导入必要的依赖项
import java.util.HashMap;
import java.util.Map;
// 定义服务接口
interface Service {
void execute();
}
// 实现类A
class ServiceImplA implements Service {
@Override
public void execute() {
System.out.println("ServiceImplA executing...");
}
}
// 实现类B
class ServiceImplB implements Service {
@Override
public void execute() {
System.out.println("ServiceImplB executing...");
}
}
// DI容器类
class Container {
private Map<Class<?>, Object> beans = new HashMap<>();
// 注册Bean
public <T> void register(Class<T> interfaceType, T instance) {
beans.put(interfaceType, instance);
}
// 获取Bean实例
public <T> T getBean(Class<T> interfaceType) {
return interfaceType.cast(beans.get(interfaceType));
}
}
// 客户端类
public class DIDemo {
public static void main(String[] args) {
// 创建容器
Container container = new Container();
// 注册服务实现到容器
container.register(Service.class, new ServiceImplA());
// 如果需要切换实现,只需更改注册的实现类
// container.register(Service.class, new ServiceImplB());
// 从容器中获取服务实例并使用
Service service = container.getBean(Service.class);
service.execute();
}
}
代码解释
-
接口定义:
Service
接口定义了一个execute
方法,作为服务的契约。
-
实现类:
ServiceImplA
和ServiceImplB
是Service
接口的两个不同实现,分别打印不同的执行信息。
-
DI容器:
Container
类充当简单的DI容器,使用一个Map
来存储接口类型与其对应的实现实例。register
方法用于将接口类型与具体实现绑定。getBean
方法用于根据接口类型获取对应的实现实例。
-
客户端使用:
- 在
DIDemo
类的main
方法中,创建了一个Container
实例。 - 通过
register
方法将Service
接口与ServiceImplA
绑定。如果需要切换实现,只需更改注册的实现类即可。 - 使用
getBean
方法获取Service
实例并调用其execute
方法。
- 在
运行结果
当运行上述代码时,输出将是:
ServiceImplA executing...
如果将注册的实现类改为ServiceImplB
,则输出将是:
ServiceImplB executing...
总结
这个简单的示例展示了如何手动实现一个基本的依赖注入容器。通过将接口与实现解耦,并在运行时动态注入所需的依赖,可以轻松地切换不同的实现而无需修改客户端代码。这种模式在实际开发中非常有用,尤其是在大型应用中,可以显著提高代码的可维护性和灵活性。