不引入DI框架如何初始化外部库需依赖注入的类A实例
无DI框架下初始化外部DI类库中类A的可行方案
以下方案均不需要在你自身开发的库中主动引入任何DI框架依赖,可根据实际场景选择:
优先查找外部库提供的非DI手动构造入口
绝大多数成熟的第三方类库,即使本身基于DI框架开发,也会预留无DI环境下的使用入口,常见形式包括静态工厂方法、Builder构造器、默认构造参数重载。先排查类A、以及A的依赖X/Y是否存在类似A.createDefault()、A.builder().build()的API,这类入口通常已经内部封装了默认依赖的初始化逻辑,不需要你手动逐层装配依赖,是成本最低的实现方式。复用外部库传递依赖的DI容器能力
你不需要主动引入DI框架依赖——当你引入该外部库时,它使用的DI框架包已经通过传递依赖进入到你的项目classpath中了,你可以直接调用该DI框架的API启动一个最小化容器,让容器帮你完成所有依赖的装配,不算你主动引入DI框架。
示例代码逻辑如下:// 实例化外部库自带的DI容器,仅扫描类A所在的最小包范围,避免加载多余资源 try (MinimalDIContainer container = new MinimalDIContainer(A.class.getPackage().getName())) { // 直接从容器获取已经完成依赖注入的A实例 A aObject = container.getBean(A.class); // 后续正常使用aObject即可,X/Y及所有深层依赖都由容器自动初始化 }这种方式不需要你梳理深层依赖关系,和你在DI项目中使用该类库的体验完全一致,适配成本极低。
手动最小化装配依赖,对非核心依赖做兜底
如果不想启动DI容器,可以顺着A的依赖链只装配核心路径上的依赖,不需要把整个依赖树的所有对象都初始化:- 从A的构造方法开始,逐层梳理你调用A的业务方法时实际会触发的依赖分支,那些不会被调用到的依赖,不需要找真实实现
- 对未被调用的非核心依赖,用JDK自带的动态代理生成兜底实现传入即可,不需要额外引入第三方组件,示例:
// 用JDK动态代理生成不会被实际调用的依赖Z的空实现 Z zFallback = (Z) Proxy.newProxyInstance( Z.class.getClassLoader(), new Class[]{Z.class}, (proxy, method, args) -> { // 确认不会触发该依赖的方法,直接返回默认值或抛异常即可 throw new UnsupportedOperationException("当前场景下不会调用该依赖方法"); } ); // 将兜底对象传入依赖链,完成X/Y和A的初始化 X xObject = new X(realCoreDependency, zFallback); Y yObject = new Y(realCoreDependency2); A aObject = new A(xObject, yObject);这种方式的装配逻辑完全可控,不会引入多余的资源初始化逻辑,适合对包体积、启动速度有严格要求的场景。
注意:不要一开始就尝试手动new全链路所有依赖,很多基于DI开发的类库中,大量构造参数是监控、配置、拦截器这类可选的横切逻辑组件,不会影响核心业务功能,用默认实现或者代理兜底完全可以正常运行。
内容的提问来源于stack exchange,提问作者Sherry
相关产品推荐
相关产品推荐

