Spring มีอะไรในโลกบ้าง


397

ฉันยังไม่พบคำจำกัดความระดับสูงของ Spring beans ที่ฉันสามารถเข้าใจได้ ฉันเห็นพวกเขาอ้างถึงบ่อยครั้งในเอกสารและหนังสือของ Grails แต่ฉันคิดว่าการเข้าใจในสิ่งที่พวกเขาจะเป็นประโยชน์ ดังนั้น Spring Spring คืออะไร? พวกเขาจะถูกนำไปใช้อย่างไร? พวกเขามีบางอย่างเกี่ยวกับการฉีดพึ่งพาหรือไม่


2
Grails สร้างขึ้นในฤดูใบไม้ผลิ หากคุณไม่คุ้นเคยกับ Spring ฉันขอแนะนำให้คุณอย่างน้อยอ่านเนื้อหาเพื่อให้คุณเข้าใจเทคโนโลยีที่คุณใช้
Jeff Storey

26
ฉันคิดว่าความคิดเห็นที่นี่ประสบจากปัญหาเดียวกันที่ OP เห็นในการอ้างอิงในเอกสาร Grails และหนังสือ: พวกเขาเป็นเรื่องง่ายสำหรับคนที่รู้อยู่แล้วว่าพวกเขาหมายถึงอะไร ฉันพบว่าบทความของ Wikipedia อธิบายได้ดีกว่าสำหรับผู้เริ่มต้น
อีเลียสดอร์เนล

12
@MarcoForberg หนึ่งในเหตุผลที่เวอร์ชั่นโบราณของ Spring เป็นที่นิยมที่สุดใน Google ก็เพราะผู้คนเชื่อมโยงกับมันจากที่ต่างๆอย่างเช่น ... static.springsource.org/spring/docs/3.2.x/ ......จะดีกว่า สถานที่ที่จะเริ่มวันนี้
Ian Roberts

5
+1 @IanRoberts นี่คือหนึ่งในปัจจุบัน
dmahapatro

มันไม่ได้ช่วยให้พวกเขาแนะนำ IoC โดยบอกว่า IoC นั้นรู้จักกันในชื่อ DI พวกเขาเกี่ยวข้องใช่ แต่ IoC กว้างกว่ามาก
Aluan Haddad

คำตอบ:


212

วัตถุที่เป็นกระดูกสันหลังของแอปพลิเคชันของคุณและได้รับการจัดการโดยคอนเทนเนอร์ Spring IoC * จะเรียกว่าถั่ว bean เป็นวัตถุที่สร้างอินสแตนซ์ประกอบและจัดการโดยคอนเทนเนอร์ Spring IoC beans เหล่านี้ถูกสร้างขึ้นด้วยข้อมูลเมตาของการกำหนดค่าที่คุณจัดหาให้กับคอนเทนเนอร์ตัวอย่างเช่นในรูปแบบของ<bean/>นิยามXML

เรียนรู้เพิ่มเติมเกี่ยวกับถั่วและขอบเขตจากSpringSource :

เมื่อคุณสร้างคำจำกัดความถั่วสิ่งที่คุณกำลังสร้างจริง ๆ เป็นสูตรสำหรับการสร้างอินสแตนซ์จริงของคลาสที่กำหนดโดยคำจำกัดความของถั่วนั้น แนวคิดที่ว่านิยามถั่วเป็นสูตรอาหารมีความสำคัญเนื่องจากหมายความว่าเช่นเดียวกับคลาสคุณอาจมีอินสแตนซ์ของวัตถุจำนวนมากที่สร้างขึ้นจากสูตรเดียว

คุณสามารถควบคุมไม่เพียง แต่การพึ่งพาต่างๆและค่าการกำหนดค่าที่จะเสียบเข้ากับวัตถุที่สร้างขึ้นจากคำจำกัดความของถั่วที่เฉพาะเจาะจง แต่ยังขอบเขตของวัตถุที่สร้างขึ้นจากคำนิยามที่เฉพาะเจาะจงถั่ว วิธีการนี้มีประสิทธิภาพมากและให้ความยืดหยุ่นในการเลือกขอบเขตของวัตถุที่คุณสร้างผ่านการกำหนดค่าแทนที่จะต้อง 'อบ' ขอบเขตของวัตถุในระดับ Java class สามารถกำหนดถั่วเพื่อนำไปใช้งานในขอบเขตใดช่วงหนึ่ง

* IoC: การกลับกันของการควบคุม


10
ดังนั้นสิ่งเหล่านี้คือวัตถุที่คอนเทนเนอร์จัดการและฉันไม่ต้องแตะต้อง แต่ถ้าฉันต้องการเข้าถึง bean เพื่อเรียกเมธอดหรือเรียกคืนคุณสมบัติฉันสามารถ "ถาม" Spring for the bean ได้หรือไม่
grantmcconnaughey

22
@grantmc มันเป็นแบบนั้นยกเว้นสิ่งที่ตรงกันข้ามของการควบคุมที่ควรจะเข้าใจในฐานะตรงกันข้ามกับ "ถาม": แทนที่จะ "ถาม" สำหรับสิ่งต่าง ๆ คุณ "ประกาศ" ว่าคุณต้องการมัน จากนั้นเมื่อคุณเริ่มแอพกรอบงานจะตรวจสอบการประกาศทั้งหมดและตั้งค่าอินสแตนซ์ที่เหมาะสม
Elias Dorneles

6
@elias ฉันจะประกาศว่าฉันต้องการมันได้อย่างไร เมื่อฉันใช้@Autowiredหรือไม่ หรือเพียงแค่เมื่อฉันทำของฉันimportได้อย่างไร
Mikhail Batcer

16
มันจะเป็นประโยชน์ในการกำหนดความหมายของ IoC สำหรับผู้มาใหม่ในฤดูใบไม้ผลิ
ลูคัส

4
@lucas เห็นด้วย IoC คือ "การผกผันของการควบคุม" ดูคำถามและคำตอบที่ยอดเยี่ยม: การฉีดการพึ่งพาและการผกผันของการควบคุมใน Spring Framework คืออะไร และการผกผันของการควบคุมคืออะไร? .
mhradek

135

Spring beans เป็นเพียงอินสแตนซ์ของวัตถุที่จัดการโดย Spring container นั่นคือมันถูกสร้างและเชื่อมต่อโดยเฟรมเวิร์กและใส่ลงใน "bag of objects" (คอนเทนเนอร์) จากที่คุณสามารถนำมาใช้ได้ในภายหลัง

ส่วน "การเดินสาย" มีสิ่งที่เกี่ยวกับการฉีดขึ้นอยู่กับความหมายคือคุณสามารถพูดว่า "ฉันจะต้องสิ่งนี้" และกรอบจะปฏิบัติตามกฎบางอย่างเพื่อให้คุณได้ตัวอย่างที่เหมาะสม

สำหรับคนที่ไม่คุ้นเคยกับ Spring ฉันคิดว่าบทความของ Wikipedia Spring มีคำอธิบายที่ดี :

ศูนย์กลางของ Spring Framework คือผกผันของคอนเทนเนอร์ควบคุมซึ่งมีวิธีการที่สอดคล้องกันในการกำหนดค่าและจัดการวัตถุ Java โดยใช้การสะท้อนกลับ คอนเทนเนอร์มีหน้าที่จัดการวงจรชีวิตของวัตถุเฉพาะ: สร้างวัตถุเหล่านี้เรียกวิธีการกำหนดค่าเริ่มต้นและกำหนดค่าวัตถุเหล่านี้โดยเชื่อมโยงเข้าด้วยกัน

วัตถุที่สร้างขึ้นโดยภาชนะที่เรียกว่าวัตถุที่มีการจัดการหรือ ถั่ว คอนเทนเนอร์สามารถกำหนดค่าได้โดยการโหลดไฟล์ XML หรือตรวจจับหมายเหตุประกอบ Java เฉพาะในคลาสการกำหนดค่า แหล่งข้อมูลเหล่านี้มีคำจำกัดความของถั่วซึ่งให้ข้อมูลที่จำเป็นในการสร้างถั่ว

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


อินสแตนซ์เป็นเพียงอีกคำหนึ่งสำหรับวัตถุ เมื่อคุณใช้ "อินสแตนซ์ของวัตถุ" คุณไม่ได้พูดถึงวัตถุนั้นหรือไม่
Flame of udun

คำถามที่น่าสนใจ ตามวิกิพีเดียฉันควรพูดว่า "อินสแตนซ์ของวัตถุ" แทน: en.wikipedia.org/wiki/Instance_(computer_science)
Elias Dorneles

2
โพรงกระต่ายลึกลงไป
Flame of udun

ฉันรู้วันนี้ว่า "วัตถุวัตถุ" (และดังนั้นอินสแตนซ์ของวัตถุ) จริง ๆ แล้วสมเหตุสมผลกับฉันเพราะฉันคุ้นเคยกับภาษาที่คลาสเป็นวัตถุ (ดังนั้นคุณจึงมีวัตถุคลาสและวัตถุ "วัตถุ" ) อย่างไรก็ตามฉันได้อัปเดตคำอธิบายเพื่อใช้ "อินสแตนซ์วัตถุ" ตามบทความ Wikipedia ^^
Elias Dorneles

1
@Ruizhi วัตถุปกติเช่นอินสแตนซ์ของคลาส - การสนทนานี้เป็นเรื่องที่เกี่ยวกับการใช้นิพจน์ที่ถูกต้องเพื่ออ้างถึงวัตถุ :)
Elias Dorneles

50

ก่อนอื่นให้เราเข้าใจ Spring:

ฤดูใบไม้ผลิเป็นกรอบน้ำหนักเบาและยืดหยุ่น

การเปรียบเทียบ:
ป้อนคำอธิบายรูปภาพที่นี่

Bean:เป็นวัตถุที่สร้างจัดการและทำลายใน Spring Container เราสามารถฉีดวัตถุเข้าไปใน Spring Container ผ่าน metadata (xml หรือหมายเหตุประกอบ) ซึ่งเรียกว่า inversion of control

การเปรียบเทียบ: ให้เราสมมติว่าชาวนากำลังมีพื้นที่เพาะปลูกโดยการเพาะเมล็ด (หรือถั่ว) ที่นี่ชาวนาเป็น Spring Framework ที่ดินเพื่อเกษตรกรรมเป็น Spring Container ถั่วเป็นถั่วในฤดูใบไม้ผลิ

ป้อนคำอธิบายรูปภาพที่นี่

เช่นเดียวกับวงจรชีวิตของถั่วเมล็ดถั่วก็มีวงจรชีวิตของตัวเองเช่นกัน

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

แหล่ง img

ต่อไปนี้เป็นลำดับวงจรชีวิตของถั่วในฤดูใบไม้ผลิ:

  • อินสแตนซ์: ขั้นแรกสปริงคอนเทนเนอร์จะค้นหาคำจำกัดความของ bean จากไฟล์ XML และสร้างอินสแตนซ์ให้กับ bean

  • เติมคุณสมบัติ: การใช้การฉีดพึ่งพาสปริงจะเติมคุณสมบัติทั้งหมดตามที่ระบุในคำนิยามของถั่ว

  • ตั้งชื่อถั่ว: ถ้าถั่วใช้BeanNameAwareอินเทอร์เฟซสปริงจะส่งรหัสของถั่วไปยังsetBeanName()วิธีการ

  • ตั้งโรงงาน Bean: ถ้า Bean ใช้BeanFactoryAwareอินเทอร์เฟซสปริงจะส่งผ่าน beanfactory ไปยังsetBeanFactory()วิธีการ

  • การเริ่มต้นล่วงหน้า: หรือที่เรียกว่ากระบวนการโพสต์ของ bean หากมีถั่วใด ๆ BeanPostProcessors ที่เกี่ยวข้องกับถั่วpostProcesserBeforeInitialization()วิธีการโทรของฤดูใบไม้ผลิ

  • ถั่วเริ่มต้น: ถ้านำไปปฏิบัติถั่วIntializingBeanมันafterPropertySet()วิธีการที่เรียกว่า หาก bean มีการประกาศเมธอด init จะมีการเรียกวิธีการกำหนดค่าเริ่มต้นที่ระบุ

  • โพสต์เริ่มต้น: - หากมีความBeanPostProcessorsเกี่ยวข้องกับถั่วpostProcessAfterInitialization()วิธีการของพวกเขาจะถูกเรียก

  • พร้อมใช้งาน: ขณะนี้ถั่วพร้อมใช้งานโดยแอปพลิเคชัน

  • ทำลาย: ถ้านำถั่วไปใช้DisposableBeanจะเรียกdestroy()วิธีการนั้น


23

คุณเข้าใจบางส่วนดี คุณต้องปรับแต่งถั่วตามความต้องการของคุณและแจ้งให้ Spring container จัดการเมื่อจำเป็นโดยใช้วิธีการที่เรียกว่า IoC ( Inversion of Control ) ประกาศเกียรติคุณโดยMartin Fowlerหรือที่เรียกว่าDependency Injection (DI)

คุณวางสายถั่วในวิธีหนึ่งดังนั้นคุณไม่จำเป็นต้องดูแลอินสแตนซ์หรือประเมินการพึ่งพาใด ๆ กับถั่ว นี้เป็นที่รู้จักกันแพร่หลายเป็นฮอลลีวู้ดหลักการ

Google เป็นเครื่องมือที่ดีที่สุดในการสำรวจเพิ่มเติมเกี่ยวกับเรื่องนี้นอกเหนือจากลิงก์ที่คุณจะได้รับจากที่นี่ในคำถามนี้ :)


2
ไม่สามารถชี้ให้เห็นได้ว่า IoC เป็นแนวคิดและ DI คือ (หนึ่งใน) เทคนิคที่สามารถใช้เพื่อให้บรรลุ IoC พวกเขาไม่ใช่นิยามที่เปลี่ยนได้
kekko12

9

ฤดูใบไม้ผลิมีภาชนะบรรจุ IoC ซึ่งพกถุงถั่ว การสร้างการบำรุงรักษาและการลบเป็นความรับผิดชอบของ Spring Container เราสามารถใส่ถั่วลงใน Spring โดย Wiring และ Auto Wiring การเดินสายไฟหมายความว่าเรากำหนดค่าด้วยตนเองลงในไฟล์ XML และ "การเดินสายไฟอัตโนมัติ" หมายความว่าเราใส่คำอธิบายประกอบลงในไฟล์ Java จากนั้น Spring จะสแกนรูทบริบทโดยอัตโนมัติที่ไฟล์กำหนดค่าจาวาสร้างและใส่ลงในถุงสปริง

นี่คือ URI ของรายละเอียดที่คุณได้รับข้อมูลเพิ่มเติมเกี่ยวกับถั่ว


8

ถั่วฤดูใบไม้ผลิเป็นชั้นเรียน แทนการทำให้คลาสเป็นอินสแตนซ์ (โดยใช้new) คุณจะได้รับอินสแตนซ์เป็นแคสต์beanให้กับประเภทคลาสของคุณจากบริบทแอปพลิเคชันโดยที่ bean เป็นสิ่งที่คุณกำหนดค่าในการกำหนดค่าบริบทของแอปพลิเคชัน ด้วยวิธีนี้แอปพลิเคชันทั้งหมดจะรักษาอินสแตนซ์ของขอบเขตเดี่ยวไว้ตลอดทั้งแอปพลิเคชัน ถั่วทั้งหมดจะเริ่มต้นได้ตามลำดับการกำหนดค่าทันทีหลังจากบริบทแอปพลิเคชันถูกสร้างขึ้น แม้ว่าคุณจะไม่ได้รับ beans ใด ๆ ในแอปพลิเคชันของคุณ แต่อินสแตนซ์ของถั่วทั้งหมดจะถูกสร้างขึ้นในเวลาหลังจากที่คุณสร้างบริบทของแอปพลิเคชันแล้ว


1
ถั่วไม่ใช่คลาส แต่วัตถุเป็นอินสแตนซ์ของคลาสที่จัดการโดยการนำคอนเทนเนอร์ไปใช้
Chatatata

7
  • Spring beans เป็นเพียงอินสแตนซ์ของวัตถุที่จัดการโดยคอนเทนเนอร์ Spring IOC

  • ภาชนะสปริง IOC พกถุงของ Bean.Bean สร้างรักษาและลบเป็นความรับผิดชอบของสปริงคอนเทนเนอร์

  • เราสามารถใส่ถั่วลงใน Spring โดย Wiring และ Auto Wiring

  • การเดินสายหมายความว่าเรากำหนดค่าด้วยตนเองลงในไฟล์ XML

  • การเดินสายอัตโนมัติหมายถึงเราใส่คำอธิบายประกอบลงในไฟล์ Java จากนั้น Spring จะสแกนรูทบริบทที่ไฟล์การกำหนดค่า java สร้างและใส่ลงในถุงของ Spring โดยอัตโนมัติ


7

A Bean เป็น POJO (วัตถุ Java เก่าแบบธรรมดา) ซึ่งจัดการโดยสปริงคอนเทนเนอร์

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

คำอธิบายประกอบ @Bean ส่งคืนวัตถุที่สปริงรีจิสเตอร์เป็น bean ในบริบทของแอปพลิเคชัน ตรรกะภายในเมธอดมีหน้าที่สร้างอินสแตนซ์

เราจะใช้คำอธิบายประกอบ @Bean เมื่อใด

เมื่อการกำหนดค่าอัตโนมัติไม่ใช่ตัวเลือก ตัวอย่างเช่นเมื่อเราต้องการวางสายส่วนประกอบจากไลบรารีบุคคลที่สามเนื่องจากไม่มีซอร์สโค้ดดังนั้นเราจึงไม่สามารถใส่คำอธิบายประกอบคลาสด้วย @Component

สถานการณ์ตามเวลาจริงอาจเป็นได้ว่ามีคนต้องการเชื่อมต่อกับที่ฝากข้อมูล Amazon S3 เนื่องจากแหล่งไม่พร้อมใช้งานเขาจะต้องสร้าง @bean

@Bean
public AmazonS3 awsS3Client() {
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsKeyId, accessKey);
    return AmazonS3ClientBuilder.standard().withRegion(Regions.fromName(region))
            .withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();
}

แหล่งที่มาสำหรับรหัสด้านบน -> https://www.devglan.com/spring-mvc/aws-s3-java

เพราะฉันพูดถึง @Component Annotation ด้านบน

@Component ระบุว่าคลาสที่ทำหมายเหตุประกอบไว้เป็น "component" คลาสดังกล่าวถือเป็นตัวเลือกสำหรับการตรวจจับอัตโนมัติเมื่อใช้การกำหนดค่าตามหมายเหตุประกอบและการสแกนพา ธ คลาส

การเพิ่มความคิดเห็นประกอบลงทะเบียนคลาสเป็น bean เดียว


2

ในฤดูใบไม้ผลิวัตถุเหล่านั้นซึ่งเป็นแกนหลักของแอปพลิเคชันของคุณและได้รับการจัดการโดยคอนเทนเนอร์ Spring IoC เรียกว่าถั่ว บีนเป็นเพียงวัตถุที่ถูกยกตัวอย่างประกอบและจัดการโดยภาชนะสปริง IoC;


1

สำหรับฤดูใบไม้ผลิวัตถุทั้งหมดเป็นถั่ว! ขั้นตอนพื้นฐานใน Spring Framework คือการกำหนดวัตถุของคุณเป็นถั่ว ถั่วเป็นอะไรก็ได้ แต่อินสแตนซ์ของวัตถุที่จะถูกสร้างขึ้นโดยกรอบงานฤดูใบไม้ผลิโดยดูที่คำจำกัดความของคลาส คำจำกัดความเหล่านี้โดยทั่วไปในรูปแบบข้อมูลเมตา เฟรมเวิร์กจะสร้างแผนสำหรับวัตถุที่จำเป็นต้องมีอินสแตนซ์ซึ่งต้องพึ่งพาการตั้งค่าและการฉีดขอบเขตของอินสแตนซ์ที่สร้างขึ้นใหม่ ฯลฯ ขึ้นอยู่กับข้อมูลเมตาของการกำหนดค่านี้

ข้อมูลเมตาสามารถจัดจำหน่ายในไฟล์ XML อย่างง่ายเช่นเดียวกับในบทแรก อีกวิธีหนึ่งสามารถให้ข้อมูลเมตาเป็นคำอธิบายประกอบหรือการกำหนดค่า Java

หนังสือ: Just Spring


1

การกำหนดค่า XML ของ Spring ประกอบด้วย Beans และ Beans โดยทั่วไปแล้วจะเป็นคลาส พวกเขาเป็นเพียง POJOs ที่เราใช้ภายใน ApplicationContext ของเรา การกำหนดถั่วสามารถถือได้ว่าเป็นการแทนที่คำหลักใหม่ ดังนั้นไม่ว่าคุณจะใช้คำหลักใหม่ในแอปพลิเคชันของคุณเช่น:

MyRepository myRepository =new MyRepository ();

ที่ที่คุณใช้คำหลักใหม่ซึ่งอยู่ที่ใดที่หนึ่งคุณสามารถดูการลบการกำหนดค่านั้นและวางลงในไฟล์ XML ดังนั้นเราจะโค้ดดังนี้:

<bean name="myRepository " 
      class="com.demo.repository.MyRepository " />

ตอนนี้เราสามารถใช้ Setter Injection / Constructor Injection ได้แล้ว ฉันกำลังใช้ Setter Injection

public class MyServiceImpl implements MyService {
    private MyRepository myRepository;
    public void setMyRepository(MyRepository myRepository)
        {
    this.myRepository = myRepository ;
        }
public List<Customer> findAll() {
        return myRepository.findAll();
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.