1。常见的三种注解注入方式对比Field注入 javaControllerpublicclassHelloController{AutowiredprivateAlphaServicealphaService;AutowiredprivateBetaServicebetaService;} field注入方式是使用最多的,原因是这种方式使用起来非常简单,代码更加简洁。Setter方法注入 javaControllerpublicclassHelloController{privateAlphaServicealphaService;privateBetaServicebetaService;AutowiredpublicvoidsetAlphaService(AlphaServicealphaService){this。alphaServicealphaService;}AutowiredpublicvoidsetBetaService(BetaServicebetaService){this。betaServicebetaService;}} 在Spring3。x刚推出的时候,Spring官方在对比构造器注入和Setter注入时,推荐使用Setter方法注入: Spring3。xConstructorbasedorsetterbasedDI?TheSpringteamgenerallyadvocatessetterinjection,becauselargenumbersofconstructorargumentscangetunwieldy,especiallywhenpropertiesareoptional。Settermethodsalsomakeobjectsofthatclassamenabletoreconfigurationorreinjectionlater。ManagementthroughJMXMBeansisacompellingusecase。 Somepuristsfavorconstructorbasedinjection。Supplyingallobjectdependenciesmeansthattheobjectisalwaysreturnedtoclient(calling)codeinatotallyinitializedstate。Thedisadvantageisthattheobjectbecomeslessamenabletoreconfigurationandreinjection。 意思是说,当出现很多注入项的时候,构造器参数可能会变得臃肿,特别是当参数时可选的时候。Setter方式注入可以让类在之后重新配置和重新注入;Constructor注入 javaControllerpublicclassHelloController{privatefinalAlphaServicealphaService;privatefinalBetaServicebetaService;AutowiredpublicHelloController(AlphaServicealphaService,BetaServicebetaService){this。alphaServicealphaService;this。betaServicebetaService;}} Spring4。x的时候,Spring官方在对比构造器注入和Setter注入时,推荐使用构造器注入方式: Spring4。xConstructorbasedorsetterbasedDI?TheSpringteamgenerallyadvocatesconstructorinjectionasitenablesonetoimplementapplicationcomponentsasimmutableobjectsandtoensurethatrequireddependenciesarenotnull。Furthermoreconstructorinjectedcomponentsarealwaysreturnedtoclient(calling)codeinafullyinitializedstate。Asasidenote,alargenumberofconstructorargumentsisabadcodesmell,implyingthattheclasslikelyhastoomanyresponsibilitiesandshouldberefactoredtobetteraddressproperseparationofconcerns。 Setterinjectionshouldprimarilyonlybeusedforoptionaldependenciesthatcanbeassignedreasonabledefaultvalueswithintheclass。Otherwise,notnullchecksmustbeperformedeverywherethecodeusesthedependency。Onebenefitofsetterinjectionisthatsettermethodsmakeobjectsofthatclassamenabletoreconfigurationorreinjectionlater。ManagementthroughJMXMBeansisthereforeacompellingusecaseforsetterinjection。 因为使用构造器注入方式注入的组件不可变,且保证了需要的依赖不为null。此外,构造器注入的组件总是能够在完全初始化的状态返回给客户端(调用方);对于很多参数的构造器说明可能包含了太多了职责,违背了单一职责原则,表示代码应该重构来分离职责到合适的地方。2。构造器注入还是Setter注入? 在对比Setter方法注入和构造器注入的时候分别引用的Spring官方文档的第二段阐述了除推荐方式的另一种方式的特点。 在Spring3。x的时候Spring推荐Setter方法注入,第二段表示:一些纯粹主义者喜欢基于构造函数的注入。提供所有对象依赖项意味着对象总是在完全初始化状态下返回给客户机(调用)代码。缺点是对象不太容易重新配置和重新注入。 在Spring4。x的时候Spring推荐构造器注入,第二段表示:Setter注入应该主要用于可选的依赖项,这些依赖项可以在类中分配合理的默认值。否则,必须在代码使用依赖项的任何地方执行非空检查。setter注入的一个好处是,setter方法使该类的对象能够在以后重新配置或重新注入。 Setter注入应该被用于可选依赖项。当没有提供它们时,类应该能够正常工作。在对象被实例化之后,依赖项可以在任何时候被更改。 构造器注入有利于强制依赖。通过在构造函数中提供依赖,您可以确保依赖对象在被构造时已准备好被使用。在构造函数中赋值的字段也可以是final的,这使得对象是完全不可变的,或者至少可以保护其必需的字段。 构造器注入还可以避免Field注入的循环依赖问题,比如在Alpha中注入Beta,又在Beta中注入Alpha。如果使用构造器注入,在Spring启动的时候就会抛出BeanCurrentlyInCreationException提醒循环依赖。 参考: https:docs。spring。iospringframeworkdocs3。1。xspringframeworkreferencehtmlbeans。htmld0e2778 https:docs。spring。iospringframeworkdocs4。2。xspringframeworkreferencehtmlbeans。htmlbeansconstructorinjection https:www。vojtechruzicka。comfielddependencyinjectionconsideredharmful https:www。cnblogs。comzhangshuaiyinp15035887。html