อะไรคือความแตกต่างระหว่าง @Inject และ @Autowired ใน Spring Framework ต้องใช้อันไหนภายใต้เงื่อนไขแบบใด


695

ฉันกำลังอ่านบล็อกบางอย่างใน SpringSource และในบล็อกใดบล็อกหนึ่งที่ผู้เขียนใช้งานอยู่@Injectและฉันคิดว่าเขาสามารถใช้งาน@Autowiredได้เช่นกัน

นี่คือส่วนของรหัส:

@Inject private CustomerOrderService customerOrderService;

ฉันไม่แน่ใจเกี่ยวกับความแตกต่างระหว่าง@Injectและ@Autowiredและจะขอบคุณถ้ามีคนอธิบายความแตกต่างและสิ่งที่จะใช้ภายใต้สถานการณ์ใด


3
ฉันไม่ได้รับคำตอบเนื่องจากฉันยังใหม่กับสิ่งนี้เช่นกัน แต่นี่อาจช่วยsakaenakajima.wordpress.com/2010/08/10/…
Sagar V


2
ความแตกต่างระหว่าง '@Inject' และ '@Autowired' ได้รับการอธิบายอย่างดีในบทความนี้alextheedom.wordpress.com/2016/02/13/20
อเล็กซ์ Theedom

คำตอบ:


720

สมมติว่าที่นี่คุณกำลังอ้างถึงjavax.inject.Injectบันทึกย่อ @Injectเป็นส่วนหนึ่งของ Java CDI ( บริบทและพึ่งพาการฉีด ) มาตรฐานการแนะนำใน Java EE 6 (JSR-299) อ่านรายละเอียดเพิ่มเติม สปริงเลือกที่จะสนับสนุนการใช้@Injectคำพ้องความหมายกับ@Autowiredคำอธิบายประกอบของตัวเอง

ดังนั้นเพื่อตอบคำถามของคุณ@Autowiredคือหมายเหตุประกอบของ Spring @Injectเป็นส่วนหนึ่งของเทคโนโลยีใหม่ของ Java ที่เรียกว่า CDI ซึ่งกำหนดมาตรฐานสำหรับการฉีดแบบพึ่งพาเหมือนกับสปริง ในแอปพลิเคชัน Spring การเพิ่มความคิดเห็นทั้งสองทำงานในลักษณะเดียวกับ Spring ได้ตัดสินใจที่จะสนับสนุนการเพิ่มความคิดเห็น JSR-299 เพิ่มเติมจากตัวเอง


115
ดังนั้นในทางทฤษฎีถ้าคุณใช้ @Inject คุณสามารถแทนที่ spring ด้วย DI Framework อื่นเช่น Guice และฉีดการพึ่งพาของคุณในลักษณะเดียวกัน
Alex Barnes

71
ที่มีความเสี่ยงต่อการเป็นคนคล่องแคล่ว: @Injectเป็น JSR (JSR-330) แยกต่างหากจาก CDI (JSR-299)
Brad Cupit

36
หากคุณพึ่งพาคำอธิบายประกอบ JSR- * เท่านั้นคุณสามารถแทนที่เฟรมเวิร์ก DI ได้ แต่คุณจะ เมื่อคุณเริ่มใช้สปริงมีโอกาสที่คุณจะใช้มันมากกว่าแค่ DI คุณจะไม่เปลี่ยนแปลง และแม้ว่าคุณจะทำไม่ใช่การค้นหา & แทนที่ที่จะสร้างหรือทำลายการเคลื่อนไหว ในทางกลับกันคำอธิบายประกอบของ Spring จะให้คุณใช้งานได้มากขึ้น การเรียนรู้กรอบงานที่ดีจะทำให้คุณใช้งานได้ยาก
Agoston Horvath

18
ฉันเห็นด้วยกับคุณว่าเราไม่เปลี่ยนกรอบ DI บ่อยครั้ง อย่างไรก็ตามหากซอร์สโค้ดของเรามีหลายแพ็คเกจและหากคุณต้องการสร้างแพ็คเกจทั่วไปที่คุณต้องการแชร์ข้ามหลายโปรเจ็กต์จากนั้นการใช้@Injectคำอธิบายประกอบ JSR จะดีกว่าการใช้@Autowiredซึ่งล็อคฐานรหัสของคุณด้วยสปริง DI
Aditya

3
การใช้@Injectเพียงอย่างเดียวจะไม่รับประกันความเป็นอิสระของกรอบงาน คุณต้องประกาศถั่วที่สามารถฉีดได้โดยไม่มีกลไกที่ขึ้นอยู่กับกรอบเช่นสปริง@Componentหรือapplication.xmlแต่ใช้@Namedและ@Singletonในระดับชั้นเรียน ไม่มีความคิดว่าโครงการ Spring ใดจะประกาศถั่วแบบนี้ในวันนี้ - ฉันไม่เคยได้ยินเกี่ยวกับโครงการใด ๆ ที่ย้ายจาก Spring มาสู่ JEE ...
Marcus K.

162

นี่คือบล็อกโพสต์ที่เปรียบเทียบ@Resource, @Injectและ@Autowiredและดูเหมือนจะไม่ได้งานที่ครอบคลุมสวย

จากลิงค์:

ยกเว้นการทดสอบ 2 และ 7 การกำหนดค่าและผลลัพธ์นั้นเหมือนกัน เมื่อฉันดูใต้ฝากระโปรงฉันได้พิจารณาแล้วว่าคำอธิบายประกอบ '@Autowired' และ '@Inject' นั้นเหมือนกัน คำอธิบายประกอบทั้งสองนี้ใช้ 'AutowiredAnnotationBeanPostProcessor' เพื่อฉีดการพึ่งพา '@Autowired' และ '@Inject' สามารถใช้แทนกันเพื่อฉีดถั่วสปริง อย่างไรก็ตามคำอธิบายประกอบ '@Resource' ใช้ 'CommonAnnotationBeanPostProcessor' เพื่อเพิ่มการอ้างอิง แม้ว่าพวกเขาจะใช้คลาสโพสต์โพสต์โพสต์ ด้านล่างนี้เป็นบทสรุปของเส้นทางการดำเนินการ

ทดสอบ 2 และ 7 ที่ผู้เขียนอ้างอิงคือ 'การฉีดตามชื่อฟิลด์' และ 'ความพยายามในการแก้ไขถั่วโดยใช้ตัวระบุที่ไม่เหมาะสม' ตามลำดับ

บทสรุปควรให้ข้อมูลทั้งหมดที่คุณต้องการ


4
บทความนั้นเป็นคำอธิบายที่ดีของคำอธิบายประกอบสามประการ ฉันต้องอ่านมันอีกครั้งหลังจากการปัดครั้งแรก แต่เป็นบทความที่ยอดเยี่ยม
โทมัส

1
ขอบคุณมาก! บทความตอบคำถามหลายคำตอบของฉันในการค้นหาความแตกต่างและความคล้ายคลึงกันระหว่าง Spring และ JavaEE รวมถึงคำถามอื่น ๆ ที่ฉันมี
Kevin Cruijssen

36

เพื่อจัดการกับสถานการณ์ที่มีการเดินสายไฟไม่มีถั่วจะสามารถใช้ได้กับชุดแอตทริบิวต์@Autowired requiredfalse

แต่เมื่อใช้@Injectงานส่วนต่อประสานผู้ให้บริการจะทำงานกับ bean ซึ่งหมายความว่า bean จะไม่ถูกฉีดโดยตรง แต่กับผู้ให้บริการ


8
นี่เป็นสิ่งสำคัญมากและถูกมองข้ามในคำตอบที่ได้รับการโหวตมากที่สุด
Igor Donin

โดยค่าเริ่มต้นที่ต้องการพารามิเตอร์ถูกตั้งค่าเป็นจริงสำหรับ Autowired Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
เงียบสงบ

25

ในฐานะของฤดูใบไม้ผลิ 3.0 ข้อเสนอฤดูใบไม้ผลิสนับสนุน JSR-330 คำอธิบายประกอบฉีดพึ่งพา ( @Inject, @Named, @Singleton)

มีส่วนที่แยกต่างหากในเอกสารเกี่ยวกับสปริงรวมถึงการเปรียบเทียบกับรายการเทียบเท่าของสปริง


คำถามที่นี่คุณหมายถึงอะไรเมื่อคุณพูดว่า Spring รองรับ JSR? คอนเทนเนอร์ไม่สนับสนุน JSR ที่เป็นอิสระของ Spring และข้อกำหนดสำหรับคอนเทนเนอร์ที่สอดคล้องกับ J2EE หรือไม่ คุณหมายถึงว่ามันล้อมรอบการทำงานหรือไม่ ถ้าสปริงไม่ "สนับสนุน" มันจะไม่มีการเพิ่มความคิดเห็นจาก javax เป็นค่าเริ่มต้นหรือไม่
Dan Chase

ไม่จำเป็นต้องเรียกใช้ Spring ในคอนเทนเนอร์ JEE คุณยังสามารถใช้ในคอนเทนเนอร์ servlet / JSP เช่น Tomcat และยังคงรองรับ JSR-330 ฤดูใบไม้ผลิเป็นภาชนะ DI แยกต่างหากมันไม่ได้ "แลกเปลี่ยน" CDI beans กับเซิร์ฟเวอร์ JEE โฮสต์หากเป็นสิ่งที่คุณหมายถึง คุณสามารถใช้ CDI ในคอนเทนเนอร์ JEE หรือ Spring beans - แต่คุณไม่สามารถใช้ทั้งสองอย่าง (นอกกรอบ)
Andre Steingress

22

ความแตกต่างที่สำคัญ (สังเกตได้จากการอ่านSpring Docs ) ระหว่าง@Autowiredและ@Injectนั่นคือ@Autowiredมีแอตทริบิวต์ 'ที่จำเป็น' ในขณะที่ @Inject ไม่มีแอตทริบิวต์ 'ที่จำเป็น'


คุณหมายถึงอะไรตามที่จำเป็น?
mattyman

2
@mattymanme จากเอกสาร"โดยค่าเริ่มต้นการลงทะเบียนอัตโนมัติล้มเหลวเมื่อใดก็ตามที่มีบอร์ดถั่วที่เป็นศูนย์พร้อมใช้งานพฤติกรรมเริ่มต้นคือการรักษาวิธีการใส่คำอธิบายประกอบก่อสร้างและเขตข้อมูลตามที่บ่งบอกถึงการพึ่งพาที่จำเป็นพฤติกรรมนี้สามารถเปลี่ยนแปลงได้ " เช่น: @Autowired(required=false). ในคำง่าย ๆ " requiredแอตทริบิวต์ระบุว่าไม่จำเป็นต้องใช้คุณสมบัติเพื่อการส่งข้อความอัตโนมัติคุณสมบัติจะถูกละเว้นหากไม่สามารถตอบรับอัตโนมัติได้"
โชคดี

มองไปที่อินเตอร์เฟสสาธารณะของซอร์สโค้ด Autowired {/ ** * ประกาศว่าต้องพึ่งพาการทำหมายเหตุประกอบหรือไม่ * / บูลีนจำเป็นต้องใช้ () เริ่มต้นจริง } อินเตอร์เฟซที่สาธารณะฉีด {}
Tarn

15

ควรใช้ @Inject ตลอดเวลา เพราะมันเป็นวิธีการกำหนดค่า java (จัดทำโดยดวงอาทิตย์) ซึ่งทำให้โปรแกรมของเราไม่เชื่อเรื่องพระเจ้าในกรอบ ดังนั้นหากคุณเรียนวิชาฤดูใบไม้ผลิด้วย

หากคุณใช้ @Autowired ระบบจะทำงานเฉพาะกับสปริงเนื่องจาก @Autowired เป็นสปริงที่มีคำอธิบายประกอบ


13
ดวงอาทิตย์ตายแล้ว ดวงอาทิตย์อยู่นาน
Amrinder Arora

6
คุณจะเปลี่ยนกรอบบ่อยแค่ไหน? แค่อยากรู้อยากเห็น
Kay

ในโครงการส่วนใหญ่ฉันเห็น Autowired มากกว่า Inject ฉันเข้าใจเหตุผลของคำตอบ แต่ไม่สามารถลงคะแนนได้
Witold Kaczurba

13

@Autowired คำอธิบายประกอบถูกกำหนดในกรอบงาน Spring

@Injectคำอธิบายประกอบเป็นคำอธิบายประกอบมาตรฐานซึ่งกำหนดไว้ในมาตรฐาน"พึ่งพาการฉีดสำหรับ Java" (JSR-330) สปริง (ตั้งแต่รุ่น 3.0) รองรับรูปแบบทั่วไปของการฉีดพึ่งพาซึ่งกำหนดไว้ในมาตรฐาน JSR-330 ( กรอบงาน Google Guiceและกรอบงาน Picocontainerรองรับรุ่นนี้ด้วย)

ด้วย@Injectสามารถฉีดการอ้างอิงถึงการใช้งานของ Providerอินเตอร์เฟซซึ่งช่วยให้การฉีดการอ้างอิงที่เลื่อนออกไป

คำอธิบายประกอบ@Injectและ@Autowired- เป็นคำเปรียบเทียบที่เกือบสมบูรณ์ เช่นเดียวกับ@Autowiredคำอธิบาย@Injectประกอบสามารถใช้คำอธิบายประกอบสำหรับคุณสมบัติการผูกอัตโนมัติวิธีการและตัวสร้าง

ตรงกันข้ามกับ@Autowiredคำ@Injectอธิบายประกอบคำอธิบายประกอบไม่มีrequiredแอตทริบิวต์ ดังนั้นหากไม่พบการอ้างอิง - จะถูกโยนทิ้งยกเว้น

นอกจากนี้ยังมีความแตกต่างในการชี้แจงของคุณสมบัติการผูก หากมีความกำกวมในการเลือกส่วนประกอบสำหรับการฉีด@Namedควรเพิ่มผู้คัดเลือก ในสถานการณ์ที่คล้ายกันสำหรับการ@Autowiredเพิ่มความคิดเห็นจะถูกเพิ่มตัวระบุ@Qualifier(JSR-330 กำหนด@Qualifierคำอธิบายประกอบของตัวเองและผ่านการ@Namedกำหนดคำอธิบายประกอบรอบคัดเลือกนี้)


แม้ว่า '@Inject' จะไม่มีแอตทริบิวต์ที่จำเป็นต้องใช้ Java Docs state: การฉีดของสมาชิกที่มีหมายเหตุประกอบด้วย '@Inject' ซึ่งดูเหมือนจะบอกเป็นนัยว่าหากสมาชิกไม่พบการฉีดจะล้มเหลว ดู Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom


12

นอกเหนือจากด้านบน:

  1. ขอบเขตเริ่มต้นสำหรับ@Autowiredถั่วเป็นซิงเกิลในขณะที่ใช้ JSR 330 @Injectคำอธิบายประกอบที่มันเป็นเหมือนต้นแบบของฤดูใบไม้ผลิ
  2. มีเทียบเท่า @Lazy ไม่มีใน JSR 330 @Injectใช้เป็น
  3. มีเทียบเท่า @value ไม่มีใน JSR 330 @Injectใช้เป็น

0

@Injectคำอธิบายประกอบเป็นหนึ่งในคอลเลกชัน JSR-330 คำอธิบายประกอบ สิ่งนี้มีการจับคู่ตามประเภทการจับคู่ตามตัวเลือกเส้นทางการดำเนินการจับคู่ตามชื่อ พา ธ การเรียกใช้งานเหล่านี้ใช้ได้สำหรับทั้ง setter และ field injection พฤติกรรมการเพิ่มความคิดเห็น@Autowiredเหมือนกับการ@Injectเพิ่มความคิดเห็น ความแตกต่างเพียงอย่างเดียวคือการ@Autowiredเพิ่มความคิดเห็นเป็นส่วนหนึ่งของ Spring Framework @Autowiredคำอธิบายประกอบยังมีเส้นทางการดำเนินการข้างต้น ดังนั้นฉันขอแนะนำ@Autowiredสำหรับคำตอบของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.