为什么官方不推荐使用 @Autowired?

为什么官方不推荐使用 @Autowired?

隐式依赖的结果就是,代码看起来简单,但维护起来费劲。

后期加个新依赖,或者改依赖顺序,分分钟把人搞糊涂。

怎么破?

用 构造函数注入替代。

@Service

publicclassMyService{

privatefinalMyRepository myRepository;

// 构造函数注入,依赖一目了然

publicMyService(MyRepository myRepository){

this.myRepository = myRepository;

}

}

这样做的好处是:

依赖清晰:谁依赖谁,直接写在构造函数里,明明白白。

更易测试:构造函数注入可以手动传入 mock 对象,方便写单元测试。

依赖清晰:谁依赖谁,直接写在构造函数里,明明白白。

更易测试:构造函数注入可以手动传入 mock 对象,方便写单元测试。

再举个例子,很人喜欢直接用 @Autowired 注入具体实现类,比如:

@Service

publicclassMyService{

@Autowired

privateSpecificRepository specificRepository;

}

表面上没毛病,但这是硬邦邦地把 MyService 和 SpecificRepository 绑死了。

万一有一天,业务改了,需要切换成另一个实现类,比如 AnotherSpecificRepository,你得改代码、改注解,连带着测试也崩。

怎么破?

用接口和构造函数注入,把依赖解耦。

@Service

publicclassMyService{

privatefinalRepository repository;

publicMyService(Repository repository){

this.repository = repository;

}

}

然后通过 Spring 的配置文件或者 @Configuration 类配置具体实现:

@Configuration

publicclassRepositoryConfig{

@Bean

publicRepository repository{

returnnewSpecificRepository;

}

}

这么搞的好处是:

灵活切换:改实现类时,不用动核心逻辑代码。

符合面向接口编程的思想:降低耦合,提升可扩展性。

灵活切换:改实现类时,不用动核心逻辑代码。

符合面向接口编程的思想:降低耦合,提升可扩展性。

有些小伙伴喜欢这么写:

@Service

publicclassMyService{

@Autowired

privateMyRepository myRepository;

publicvoiddoSomething{

myRepository.save; // 啪!NullPointerException

}

}

问题在哪?如果 Spring 容器还没来得及注入依赖,你的代码就跑了(比如在构造函数或初始化方法中直接调用依赖),结果自然就是 NullPointerException。

怎么破?

用构造函数注入,彻底干掉 null 的可能性。

@Service

publicclassMyService{

privatefinalMyRepository myRepository;

publicMyService(MyRepository myRepository){

this.myRepository = myRepository; // 确保依赖在对象初始化时就已注入

}

publicvoiddoSomething{

myRepository.save;

}

}

构造函数注入的另一个优点是: 依赖注入是强制的,Spring 容器不给你注入就报错,让问题早暴露。

4.自动装配容易搞出迷惑行为

Spring 的自动装配机制有时候是“黑魔法”,尤其是当你的项目里有个候选 Bean 时。比如:

@Service

publicclassMyService{

@Autowired

privateRepository repository; // 容器里有两个 Repository 实现类,咋办?

}

如果有两个实现类,比如 SpecificRepository 和 AnotherRepository,Spring 容器直接报错。解决方法有两种:

指定 @Primary。

用 @Qualifier 手动指定。

指定 @Primary。

用 @Qualifier 手动指定。

但这些方式都让代码看起来更复杂了,还可能踩坑。

怎么破?

构造函数注入 + 显式配置。

@Configuration

publicclassRepositoryConfig{

@Bean

publicRepository repository{

returnnewSpecificRepository;

}

}

你明确告诉 Spring 该用哪个实现类,别让容器帮你猜,省得以后“配错药”。

5. 写单元测试非常痛苦

最后,聊聊测试的事儿。

@Autowired 依赖 Spring 容器才能工作,但写单元测试时,大家都不想起 Spring 容器(麻烦、慢)。结果就是:

字段注入:没法手动传入 mock 对象。

自动装配:有时候不清楚用的 Bean 是哪个,测试难搞。

字段注入:没法手动传入 mock 对象。

自动装配:有时候不清楚用的 Bean 是哪个,测试难搞。

构造函数注入天生就是为单元测试设计的。

publicclassMyServiceTest{

@Test

publicvoidtestDoSomething{

MyRepository mockRepository = mock(MyRepository . class) ;

MyService myService = newMyService(mockRepository);

// 测试逻辑

}

}

看见没?

直接传入 mock 对象,测试简单、优雅。

总结

简单总结下问题:

隐式依赖让代码可读性差。

强耦合违背面向接口编程。

字段注入容易 NPE。

自动装配有坑。

单元测试不好写。

隐式依赖让代码可读性差。

强耦合违背面向接口编程。

字段注入容易 NPE。

自动装配有坑。

单元测试不好写。

那到底咋办?用 构造函数注入,清晰、稳健、测试友好,官方推荐不是没道理的。

但话说回来,@Autowired 也不是不能用,只是你得分场景。

开发中,养成用构造函数注入的习惯,能让你的代码更健壮,少挖坑,干活!返回搜狐,查看更多

相关创意

仿皮沙发能用多久?仿皮沙发和真皮沙发要怎么进行区分?
什么是单点登录 (SSO)? 含义及其运作方式?
电脑怎么进入编程模式,如何进入电脑编程模式?
阴阳师镰鼬最多刷新点介绍
365bet手机投注网

阴阳师镰鼬最多刷新点介绍

📅 10-04 👁️ 8112
作为一名大学生,为什么会直接选择IT培训?IT培训有什么好处?
如何查看路由器IP地址(管理后台地址)
365bet手机投注网

如何查看路由器IP地址(管理后台地址)

📅 09-01 👁️ 6007
怎么用锅煮粥(怎么用锅煮粥要多久)
hse365平台

怎么用锅煮粥(怎么用锅煮粥要多久)

📅 07-12 👁️ 9516
开店名字怎么取?这5大原则+100个精选案例助你生意兴隆!