You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular拦截器场景下单例LoginService被创建两次如何解决

问题原因

你配置的两套注入规则触发了LoginService的两次实例化:

  • 第一次实例化:当业务代码注入AbstractLoginService时,Angular匹配AppModule中配置的{ provide: AbstractLoginService, useClass: LoginService }规则,创建第一个LoginService实例。
  • 第二次实例化:拦截器中直接注入具体类LoginService,而LoginService自身配置了providedIn: 'root',Angular会从根注入器创建第二个独立的LoginService实例返回给拦截器。
修复方案

两步修改即可保证LoginService全局单例:

  1. 统一使用抽象类作为注入令牌,修改拦截器的注入类型,将具体类LoginService替换为抽象类AbstractLoginService
    修改后的HTTPDemo.interceptor.ts代码:
@Injectable({ providedIn: 'root' })
export class HTTPDemoInterceptor implements HttpInterceptor {
    constructor(
        // 这里换成抽象类作为注入类型
        private loginService: AbstractLoginService,
    ) { 
      console.log('CONSTRUCTOR HTTPDemoInterceptor');
    }
    // 其余拦截逻辑不变
}
  1. 移除LoginService的全局自动提供配置,避免后续误注入具体类时重复生成实例,修改login.service.ts的装饰器:
// 去掉providedIn: 'root',仅保留空@Injectable
@Injectable()
export class LoginService implements AbstractLoginService {
    private timestamp = 0
    constructor() {
        this.timestamp = +new Date();
        console.trace('CONSTRUCTOR LoginService', this.timestamp);
    }
    // 其余业务逻辑不变
}

额外提示:原LoginService的构造函数中重复声明了timestamp属性,属于语法问题,建议删除构造函数的timestamp参数,直接给类属性赋值即可

修改完成后所有依赖AbstractLoginService的场景都会拿到同一个LoginService实例,不会再重复构造。


内容的提问来源于stack exchange,提问作者Kamil Kiełczewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 10:39:02