跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • @Autowired 注入转换为构造器注入,导致的构造器代码臃肿,除了 Lombok 外还有别的解决方案吗?
未分類
7 10 月 2020

@Autowired 注入转换为构造器注入,导致的构造器代码臃肿,除了 Lombok 外还有别的解决方案吗?

@Autowired 注入转换为构造器注入,导致的构造器代码臃肿,除了 Lombok 外还有别的解决方案吗?

資深大佬 : vate32 4

各博客文章说的都是要么使用 Lombok 的 @ RequiredArgsConstructor 注解,要么“考虑这个类是符合足单一职责原则了,将这个类拆分为多个类”。可是对于前者,项目不一定使用 Lombok,对于后者,实际业务情况可能使用很多个依赖类,拆分不太现实。请问还有别的优雅的解决方案吗?
大佬有話說 (27)

  • 資深大佬 : NULL2020

    为什么要换,@Autowired 不香吗?

  • 資深大佬 : lychs1998

    @NULL2020 构造器注入也是 @Autowired 。

  • 主 資深大佬 : vate32

    @NULL2020 使用 Autowired 进行注入有空指针风险(例如在构造函数里使用了注入的对象,但是构造函数的调用优先于自动注入,此时调用就会抛出空指针错误),也不方便进行测试,Spring 官方也不推荐使用( Spring Team recommends “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.)。话说平常 IDE 的警告你们都不看的吗

  • 資深大佬 : vantis

    心情好就去改改 如果是别人代码我就不动
    (程序员怎么回去看 WARNING 233)

  • 資深大佬 : NULL2020

    规则是死的,人是活的,怎么顺手怎么来

  • 資深大佬 : intmax2147483647

    @NULL2020 顺手写一个 BUG

  • 資深大佬 : gdtdpt

    看场景吧,也不是说一定不能用非构造器注入的方式,如果你确实需要在一个 bean 的构造函数中做些什么,才需要把相关的 bean 以构造器注入的方式注入到当前实例。
    如果不想这样,那也可以注入 ApplicationContext,具体需要的 Bean 可以从 ApplicationContext 中获取,但是这样做也有可能获取的 Bean 为 null 。
    所以我觉得如果没遇到注入的 Bean 为 null 的情况下,setter 注入,field 注入还是 constructor 注入三种方式不必太纠结,当真正遇到了问题再去分析 bean 的 生成顺序和代码的执行顺序比较好。

  • 資深大佬 : Jooooooooo

    臃肿的缺点是?

  • 資深大佬 : hpashencedany1

    拆吧, 我在慢慢拆

  • 資深大佬 : sheng3233386

    我们都用 @Resource

  • 資深大佬 : Resource

    @sheng3233386 #10 谢邀

  • 資深大佬 : Boyce

    @Resource 哈哈哈哈

  • 資深大佬 : chendy

    感觉这个注入就是配合 lombok 最舒服
    不过确实有些场景不能用,比如 RestTemplateBuilder 这种
    不过反正可以自动生成自动补全
    如果一个 bean 要注入的 bean 太多了,考虑重构一下吧

  • 資深大佬 : xiangyuecn

    @Resource 这个注解确实牛逼

  • 資深大佬 : MatthewHan

    @NULL2020 #1 Autowired 都要被淘汰了

  • 主 資深大佬 : vate32

    @Jooooooooo 臭长臭长的,构造函数参数列表很长,不好维护(个人观点)。

    @sheng3233386 直接使用名称的吗,但是这个能够避免上面说的空指针错误吗,好像跟直接使用 autowired 是一样的。

    @chendy 写着着实很爽,但是担心有的地方不让用 Lombok (似乎想多了)

    @gdtdpt 多谢大佬指点,还是得看实际情况来。从 ApplicationContext 获取到 Bean 的方法还没用到过,去学习一下。

  • 資深大佬 : yuhaoyang222

    建造者模式

  • 資深大佬 : STRRL

    不清楚 lz 这个问题是在刚刚想做还是已经做一段时间了,不知道有没有遇到过循环依赖的问题。

    constructor 注入需要你先有一个 constructor, 所以手写一个也好 lombok 生成一个也好,还是 IDEA command+N generate 一个也好,都是不错的选择。

    我 jio 得循环依赖才是无法使用 constructor 注入的罪魁祸首,毕竟即使你的 constructor 需要的参数再多,也就是一个注解或者一个快捷键自动生成的事。由于设计上的失误导致的循环依赖会使你压根用不了构造器注入,而且有循环依赖的项目多多少少会有其他的 badsmell …(破窗。。。

  • 資深大佬 : linvaux

    公司禁止使用 lombok,而且,这玩意儿代码能有多冗余?只是自己强迫症发作了吧

  • 資深大佬 : Aresxue

    一般无非就还是插件, idea 官方能出个功能是最好的,虽然构造器更好但如果没有其他配合还是用 field 注入吧,至少不用在新加服务后还要改构造器

  • 資深大佬 : wallfacers

    @lychs1998 构造器注入不是 @Autowired,两者实现区别很大。 @Autowired 是通过 AutowiredAnnotationBeanPostProcessor 进行注入的,而构造器注入是在 Bean 的创建阶段,就会去找到最匹配的构造器,并且准备好构造器需要依赖的 Bean

  • 資深大佬 : ic2y

    @vate32 Autowired 注入在多人大型项目里,我碰到过一些问题,因为团队成员的理解不一样:容易造成滥用(可能是为了复用某个能力,就注入一堆 bean )、循环依赖(底层模型注入了高层模型的 bean,可能交叉)、多模块的项目很难管理(有种拔出萝卜带出泥的感觉,因为 A 和 B 项目共享了模块 C,B 项目在 C 模块增加了一个 Autowired 注入,A 项目没有感知)。

    我自己认为,构造器注入更好,Spring 官方也推荐,构造器注入在一定程度上:强迫开发者去思考,当前的 bean 为什么要注入其他的依赖。

    如果你用了 Lombok 自动实现了构造器注入,那么这种强迫开发者去思考的动机就没有了,还不如直接 Autowired 。

    手动的用构造器注入(除了某些特定的类,例如 Controller 之类的),我认为有如下优点:
    1.强迫我自己思考:这个注入是否是必须的,是否可以用工具类?用设计模式?或者其他的优雅方法来实现这个逻辑设计。
    2.注入的改变是可感知的。在大型多模块架构的协作工程里,可能很有用。大家在协作里复用了模块 C,一旦你在模块里增加了注入参数,那么其他人用到了模块 C 注入 bean,会立刻编译错误。
    3.因为大型工程里,一般会把某个模块作为一个 jar 包,让其他应用引用,Configuration 里动态声明 Bean 的时候,感觉更从容。因为我知道当前的 bean 所有的依赖都是构造方式注入,我可以从容选择一组自己指定的 bean 进去组装。
    4.某种意义上,实现了业务代码和 Spring 框架的解耦。因为构造器注入的话,就像在写普通的 java 的 pojo 。我们不需要 @Autowired 不需要 @Service 和 @Component,业务类里基本不会 import spring 的东西,依赖 Configuration 的动态装配能力,从构造注入声明了一个个的 bean,完全可控(适合有洁癖的人)。如果有场景,需要移植的话,会很容易,例如:从 Spring 框架移植到 google 的 guice 框架。

    那么,如果构造器注入的 bean 很多的时候,也是一个强迫性的提醒:是实时思考当前的 bean 的设计问题了。

  • 資深大佬 : wysnylc

    构造器无法解决循环依赖问题,spring 推荐构造器注入同时也说了该问题
    没能力解决这个问题的就别瞎折腾

  • 資深大佬 : EminemW

    不可以实现 InitializingBean 接口嘛

  • 資深大佬 : br00k

    推荐构造方法注入。IDE 可以根据属性自动生成构造方法。
    因为构造方法注入默认是不能循环引用,循环引用更多是代码结构或设计不合理,这样能约束你的代码,逼迫你去思考避免循环引用,这是非常好的。
    至于说非要循环引用,请在构造参数上使用 @Lazy 就可以了。这个是不建议的,如果都这样写,还不如用 autowired 。
    我的习惯是只有在 Bean 自己注入自己才会用 @Lazy,这样是避免使用 this 调用内部方法 AOP 失效。

  • 資深大佬 : 1194129822

    现在大多数项目还是 Filed 注入,spring3 推荐 setter 注入,4 推荐构造器注入,且 4.3 后如果 bean 中有构造器,则不需要 @Autowired, 就已经使用构造器注入,复杂的是 spring 构造器,setter,Filed 注入可以一起工作,所以你使用 Lombok,只要用了 AllArgsContructor/RequiredArgsConstructor,就不需要其他 spring 注解。而且构造器注入无法解决循环依赖,而且是生成的构造器,你也无法操作,所以 @Lazy 解决循环依赖不可用. 但是依然可以在需要循环依赖的 Bean 上使用 @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)提前暴露代理 Bean,不过 spring 官方推荐构造器注入的原因就是程序员自己解决循环依赖

  • 資深大佬 : sheng3233386

    @vate32 避免不了空指针,在构造函数的调用逻辑建议在 PostConstruct 注解的方法里执行。Resource 没有你说的 warning,哈哈

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具