ฤดูใบไม้ผลิ - คู่มือฉบับย่อ
Spring เป็นเฟรมเวิร์กการพัฒนาแอปพลิเคชันยอดนิยมสำหรับ Java ระดับองค์กร นักพัฒนาหลายล้านคนทั่วโลกใช้ Spring Framework เพื่อสร้างโค้ดที่มีประสิทธิภาพสูงทดสอบได้ง่ายและใช้ซ้ำได้
Spring framework เป็นแพลตฟอร์ม Java แบบโอเพ่นซอร์ส เริ่มแรกเขียนโดย Rod Johnson และเผยแพร่ครั้งแรกภายใต้ลิขสิทธิ์ Apache 2.0 ในเดือนมิถุนายน พ.ศ. 2546
สปริงมีน้ำหนักเบาเมื่อมีขนาดและความโปร่งใส Spring framework เวอร์ชันพื้นฐานมีขนาดประมาณ 2MB
คุณสมบัติหลักของ Spring Framework สามารถใช้ในการพัฒนาแอปพลิเคชัน Java ใด ๆ แต่มีส่วนขยายสำหรับการสร้างเว็บแอปพลิเคชันที่ด้านบนของแพลตฟอร์ม Java EE Spring Framework มีเป้าหมายเพื่อให้การพัฒนา J2EE ใช้งานง่ายขึ้นและส่งเสริมแนวทางปฏิบัติในการเขียนโปรแกรมที่ดีโดยการเปิดใช้โมเดลการเขียนโปรแกรมแบบ POJO
ประโยชน์ของการใช้ Spring Framework
ต่อไปนี้เป็นรายการประโยชน์บางประการของการใช้ Spring Framework -
Spring ช่วยให้นักพัฒนาสามารถพัฒนาแอปพลิเคชันระดับองค์กรโดยใช้ POJO ประโยชน์ของการใช้ POJO เพียงอย่างเดียวคือคุณไม่จำเป็นต้องมีผลิตภัณฑ์คอนเทนเนอร์ EJB เช่นแอปพลิเคชันเซิร์ฟเวอร์ แต่คุณมีตัวเลือกในการใช้เฉพาะคอนเทนเนอร์ servlet ที่มีประสิทธิภาพเช่น Tomcat หรือผลิตภัณฑ์เชิงพาณิชย์บางอย่าง
ฤดูใบไม้ผลิจัดแบบแยกส่วน แม้ว่าแพ็กเกจและคลาสจะมีจำนวนมาก แต่คุณต้องกังวลเฉพาะกับแพ็กเกจที่คุณต้องการและไม่สนใจส่วนที่เหลือ
Spring ไม่ได้สร้างวงล้อขึ้นมาใหม่ แต่จะใช้ประโยชน์จากเทคโนโลยีที่มีอยู่บางอย่างเช่นเฟรมเวิร์ก ORM เฟรมเวิร์กการบันทึก JEE ควอตซ์และ JDK และเทคโนโลยีมุมมองอื่น ๆ
การทดสอบแอปพลิเคชันที่เขียนด้วย Spring นั้นทำได้ง่ายเนื่องจากมีการย้ายโค้ดที่ขึ้นกับสภาพแวดล้อมมาไว้ในกรอบ นอกจากนี้ด้วยการใช้ JavaBeanstyle POJOs มันจะง่ายกว่าที่จะใช้การฉีดพึ่งพาสำหรับการฉีดข้อมูลทดสอบ
เฟรมเวิร์กเว็บของ Spring เป็นเฟรมเวิร์ก MVC บนเว็บที่ได้รับการออกแบบมาอย่างดีซึ่งเป็นทางเลือกที่ดีสำหรับเว็บเฟรมเวิร์กเช่น Struts หรือเฟรมเวิร์กเว็บอื่น ๆ ที่ได้รับความนิยมน้อย
Spring มอบ API ที่สะดวกในการแปลข้อยกเว้นเฉพาะเทคโนโลยี (ยกตัวอย่างโดย JDBC, Hibernate หรือ JDO) ให้เป็นข้อยกเว้นที่สอดคล้องกันและไม่ได้ตรวจสอบ
ตู้คอนเทนเนอร์ IoC น้ำหนักเบามักจะมีน้ำหนักเบาโดยเฉพาะอย่างยิ่งเมื่อเทียบกับคอนเทนเนอร์ EJB เป็นต้น สิ่งนี้มีประโยชน์สำหรับการพัฒนาและปรับใช้แอปพลิเคชันบนคอมพิวเตอร์ที่มีหน่วยความจำและทรัพยากร CPU จำกัด
Spring มีอินเทอร์เฟซการจัดการธุรกรรมที่สอดคล้องกันซึ่งสามารถปรับขนาดลงไปที่ธุรกรรมภายในเครื่อง (เช่นใช้ฐานข้อมูลเดียว) และปรับขนาดเป็นธุรกรรมทั่วโลก (โดยใช้ JTA เป็นต้น)
การพึ่งพาการฉีด (DI)
เทคโนโลยีที่ Spring ถูกระบุมากที่สุดคือ Dependency Injection (DI)รสชาติของการผกผันของการควบคุม Inversion of Control (IoC)เป็นแนวคิดทั่วไปและสามารถแสดงออกได้หลายวิธี Dependency Injection เป็นเพียงตัวอย่างที่ชัดเจนของ Inversion of Control
เมื่อเขียนแอ็พพลิเคชัน Java ที่ซับซ้อนคลาสแอ็พพลิเคชันควรเป็นอิสระจากคลาส Java อื่น ๆ ให้มากที่สุดเพื่อเพิ่มความเป็นไปได้ในการนำคลาสเหล่านี้กลับมาใช้ใหม่และทดสอบโดยไม่ขึ้นกับคลาสอื่น ๆ ในขณะทดสอบยูนิต Dependency Injection ช่วยในการรวมชั้นเรียนเหล่านี้เข้าด้วยกันและในขณะเดียวกันก็ทำให้พวกเขาเป็นอิสระ
การฉีดพึ่งพาคืออะไรกันแน่? ลองดูสองคำนี้แยกกัน ส่วนการพึ่งพาแปลเป็นการเชื่อมโยงระหว่างสองคลาส ตัวอย่างเช่นคลาส A ขึ้นอยู่กับคลาส B ทีนี้มาดูส่วนที่สองคือการฉีด ทั้งหมดนี้หมายความว่าคลาส B จะถูกไอโอซีฉีดเข้าไปในคลาส A
การฉีดแบบพึ่งพาสามารถเกิดขึ้นได้ในวิธีการส่งผ่านพารามิเตอร์ไปยังตัวสร้างหรือโดยหลังการก่อสร้างโดยใช้วิธีเซ็ตเตอร์ เนื่องจาก Dependency Injection เป็นหัวใจสำคัญของ Spring Framework เราจะอธิบายแนวคิดนี้ในบทที่แยกต่างหากพร้อมกับตัวอย่างที่เกี่ยวข้อง
การเขียนโปรแกรมเชิงภาพ (AOP)
องค์ประกอบสำคัญอย่างหนึ่งของ Spring คือ Aspect Oriented Programming (AOP)กรอบ. เรียกว่าฟังก์ชันที่ครอบคลุมหลายจุดของแอปพลิเคชันcross-cutting concernsและความกังวลข้ามมิติเหล่านี้เป็นแนวคิดที่แยกออกจากตรรกะทางธุรกิจของแอปพลิเคชัน มีตัวอย่างด้านต่างๆที่ดีเช่นการบันทึกการทำธุรกรรมที่เปิดเผยความปลอดภัยการแคชเป็นต้น
หน่วยหลักของโมดูลาร์ใน OOP คือคลาสในขณะที่ใน AOP หน่วยของโมดูลาร์คือด้าน DI ช่วยให้คุณแยกวัตถุในแอปพลิเคชันของคุณออกจากกันในขณะที่ AOP ช่วยให้คุณแยกข้อกังวลข้ามการตัดออกจากวัตถุที่ส่งผลกระทบ
โมดูล AOP ของ Spring Framework มีการใช้งานการเขียนโปรแกรมเชิงแง่มุมซึ่งช่วยให้คุณสามารถกำหนดตัวดักจับวิธีการและตัวชี้จุดเพื่อแยกโค้ดออกอย่างหมดจดซึ่งใช้ฟังก์ชันการทำงานที่ควรแยกออกจากกัน เราจะพูดคุยเพิ่มเติมเกี่ยวกับแนวคิด Spring AOP ในบทที่แยกต่างหาก
Spring อาจเป็นร้านค้าครบวงจรสำหรับแอปพลิเคชันองค์กรทั้งหมดของคุณ อย่างไรก็ตาม Spring เป็นแบบแยกส่วนช่วยให้คุณสามารถเลือกและเลือกโมดูลที่เหมาะกับคุณโดยไม่ต้องนำส่วนที่เหลือเข้ามา ส่วนต่อไปนี้ให้รายละเอียดเกี่ยวกับโมดูลทั้งหมดที่มีอยู่ใน Spring Framework
Spring Framework มีโมดูลประมาณ 20 โมดูลซึ่งสามารถใช้ได้ตามความต้องการของแอปพลิเคชัน
คอนเทนเนอร์หลัก
Core Container ประกอบด้วยโมดูล Core, Beans, Context และ Expression Language ซึ่งมีรายละเอียดดังนี้ -
Core โมดูลจัดเตรียมส่วนพื้นฐานของเฟรมเวิร์กรวมถึงคุณสมบัติ IoC และ Dependency Injection
Bean โมดูลจัดเตรียม BeanFactory ซึ่งเป็นการใช้งานรูปแบบโรงงานที่ซับซ้อน
Contextโมดูลสร้างขึ้นบนฐานที่มั่นคงที่จัดเตรียมโดยโมดูล Core and Beans และเป็นสื่อในการเข้าถึงวัตถุใด ๆ ที่กำหนดและกำหนดค่าไว้ อินเทอร์เฟซ ApplicationContext เป็นจุดโฟกัสของโมดูลบริบท
SpEL โมดูลจัดเตรียมภาษานิพจน์ที่มีประสิทธิภาพสำหรับการสืบค้นและจัดการกราฟออบเจ็กต์ที่รันไทม์
การเข้าถึง / การรวมข้อมูล
ชั้นการเข้าถึง / การรวมข้อมูลประกอบด้วยโมดูล JDBC, ORM, OXM, JMS และธุรกรรมซึ่งมีรายละเอียดดังนี้ -
JDBC โมดูลมีเลเยอร์ JDBC-Abstraction ที่ขจัดความจำเป็นในการเข้ารหัสที่เกี่ยวข้องกับ JDBC ที่น่าเบื่อ
ORM โมดูลจัดเตรียมเลเยอร์การรวมสำหรับ API การทำแผนที่เชิงสัมพันธ์เชิงวัตถุยอดนิยม ได้แก่ JPA, JDO, Hibernate และ iBatis
OXM โมดูลจัดเตรียมเลเยอร์ที่เป็นนามธรรมที่สนับสนุนการใช้งานการแม็พ Object / XML สำหรับ JAXB, Castor, XMLBeans, JiBX และ XStream
Java Messaging Service JMS โมดูลมีคุณสมบัติสำหรับการผลิตและการบริโภคข้อความ
Transaction โมดูลรองรับการจัดการธุรกรรมแบบเป็นโปรแกรมและแบบเปิดเผยสำหรับคลาสที่ใช้อินเทอร์เฟซพิเศษและ POJO ทั้งหมดของคุณ
เว็บ
เลเยอร์เว็บประกอบด้วยโมดูล Web, Web-MVC, Web-Socket และ Web-Portlet ซึ่งมีรายละเอียดดังนี้ -
Web โมดูลมีคุณสมบัติการรวมพื้นฐานบนเว็บเช่นฟังก์ชันการอัปโหลดไฟล์แบบหลายส่วนและการกำหนดค่าเริ่มต้นของคอนเทนเนอร์ IoC โดยใช้ตัวรับฟัง servlet และบริบทแอปพลิเคชันเชิงเว็บ
Web-MVC โมดูลประกอบด้วยการใช้งาน Model-View-Controller (MVC) ของ Spring สำหรับเว็บแอปพลิเคชัน
Web-Socket โมดูลให้การสนับสนุนสำหรับการสื่อสารสองทางบน WebSocket ระหว่างไคลเอนต์และเซิร์ฟเวอร์ในเว็บแอปพลิเคชัน
Web-Portlet โมดูลจัดเตรียมการนำ MVC ไปใช้ในสภาวะแวดล้อมพอร์ตเล็ตและมิเรอร์การทำงานของโมดูล Web-Servlet
เบ็ดเตล็ด
มีโมดูลที่สำคัญอื่น ๆ อีกเล็กน้อยเช่น AOP, Aspects, Instrumentation, Web และ Test module ซึ่งมีรายละเอียดดังต่อไปนี้ -
AOP โมดูลมีการใช้งานการเขียนโปรแกรมเชิงแง่มุมช่วยให้คุณสามารถกำหนดตัวสกัดกั้นเมธอดและพอยต์ชอตเพื่อแยกโค้ดออกอย่างหมดจดซึ่งใช้ฟังก์ชันการทำงานที่ควรแยกออกจากกัน
Aspects โมดูลให้การทำงานร่วมกับ AspectJ ซึ่งเป็นกรอบงาน AOP ที่ทรงพลังและเป็นผู้ใหญ่อีกครั้ง
Instrumentation โมดูลให้การสนับสนุนเครื่องมือคลาสและการใช้งานตัวโหลดคลาสที่จะใช้ในแอ็พพลิเคชันเซิร์ฟเวอร์บางตัว
Messagingโมดูลให้การสนับสนุนสำหรับ STOMP เป็นโปรโตคอลย่อยของ WebSocket เพื่อใช้ในแอปพลิเคชัน นอกจากนี้ยังสนับสนุนรูปแบบการเขียนโปรแกรมคำอธิบายประกอบสำหรับการกำหนดเส้นทางและการประมวลผลข้อความ STOMP จากไคลเอนต์ WebSocket
Test โมดูลรองรับการทดสอบส่วนประกอบ Spring ด้วยกรอบ JUnit หรือ TestNG
บทนี้จะแนะนำคุณเกี่ยวกับวิธีการเตรียมสภาพแวดล้อมการพัฒนาเพื่อเริ่มงานของคุณกับ Spring Framework นอกจากนี้ยังสอนวิธีตั้งค่า JDK, Tomcat และ Eclipse บนเครื่องของคุณก่อนที่คุณจะตั้งค่า Spring Framework -
ขั้นตอนที่ 1 - ตั้งค่า Java Development Kit (JDK)
คุณสามารถดาวน์โหลด SDK เวอร์ชันล่าสุดได้จากไซต์ Java ของ Oracle - ดาวน์โหลด Java SE คุณจะพบคำแนะนำในการติดตั้ง JDK ในไฟล์ที่ดาวน์โหลดทำตามคำแนะนำที่กำหนดเพื่อติดตั้งและกำหนดค่าการตั้งค่า สุดท้ายตั้งค่าตัวแปรสภาพแวดล้อม PATH และ JAVA_HOME เพื่ออ้างถึงไดเร็กทอรีที่มี java และ javac โดยทั่วไปคือ java_install_dir / bin และ java_install_dir ตามลำดับ
หากคุณใช้ Windows และติดตั้ง JDK ใน C: \ jdk1.6.0_15 คุณจะต้องใส่บรรทัดต่อไปนี้ในไฟล์ C: \ autoexec.bat ของคุณ
set PATH=C:\jdk1.6.0_15\bin;%PATH%
set JAVA_HOME=C:\jdk1.6.0_15
หรืออีกวิธีหนึ่งใน Windows NT / 2000 / XP คุณจะต้องคลิกขวาที่ My Computer เลือก Properties → Advanced → Environment Variables จากนั้นคุณจะต้องอัปเดตค่า PATH และคลิกปุ่มตกลง
ใน Unix (Solaris, Linux ฯลฯ ) หากติดตั้ง SDK ใน /usr/local/jdk1.6.0_15 และคุณใช้ C เชลล์คุณจะต้องใส่สิ่งต่อไปนี้ลงในไฟล์. cshrc ของคุณ
setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.6.0_15
หรือหากคุณใช้ Integrated Development Environment (IDE) เช่น Borland JBuilder, Eclipse, IntelliJ IDEA หรือ Sun ONE Studio คุณจะต้องคอมไพล์และรันโปรแกรมง่ายๆเพื่อยืนยันว่า IDE รู้ว่าคุณติดตั้ง Java ไว้ที่ใด มิฉะนั้นคุณจะต้องดำเนินการตั้งค่าที่เหมาะสมตามที่ระบุในเอกสารของ IDE
ขั้นตอนที่ 2 - ติดตั้ง Apache Common Logging API
คุณสามารถดาวน์โหลด Apache Commons Logging API เวอร์ชันล่าสุดได้จาก https://commons.apache.org/logging/. เมื่อคุณดาวน์โหลดการติดตั้งแล้วให้แกะการกระจายไบนารีในตำแหน่งที่สะดวก ตัวอย่างเช่นใน C: \ commons-logging-1.1.1 บน Windows หรือ /usr/local/commons-logging-1.1.1 บน Linux / Unix ไดเร็กทอรีนี้จะมีไฟล์ jar ต่อไปนี้และเอกสารสนับสนุนอื่น ๆ เป็นต้น
ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าตัวแปร CLASSPATH บนไดเร็กทอรีนี้อย่างถูกต้องมิฉะนั้นคุณจะประสบปัญหาขณะเรียกใช้แอปพลิเคชันของคุณ
ขั้นตอนที่ 3 - ตั้งค่า Eclipse IDE
ตัวอย่างทั้งหมดในบทช่วยสอนนี้เขียนขึ้นโดยใช้ Eclipse IDE ดังนั้นเราขอแนะนำให้คุณติดตั้ง Eclipse เวอร์ชันล่าสุดในเครื่องของคุณ
ในการติดตั้ง Eclipse IDE ให้ดาวน์โหลดไบนารี Eclipse ล่าสุดจาก https://www.eclipse.org/downloads/. เมื่อคุณดาวน์โหลดการติดตั้งแล้วให้แกะการกระจายไบนารีในตำแหน่งที่สะดวก ตัวอย่างเช่นใน C: \ eclipse บน Windows หรือ / usr / local / eclipse บน Linux / Unix และสุดท้ายตั้งค่าตัวแปร PATH ให้เหมาะสม
Eclipse สามารถเริ่มต้นได้โดยดำเนินการคำสั่งต่อไปนี้บนเครื่อง Windows หรือคุณสามารถดับเบิลคลิกที่ eclipse.exe
%C:\eclipse\eclipse.exe
Eclipse สามารถเริ่มต้นได้โดยดำเนินการคำสั่งต่อไปนี้บนเครื่อง Unix (Solaris, Linux และอื่น ๆ ) -
$/usr/local/eclipse/eclipse
หลังจากเริ่มต้นสำเร็จหากทุกอย่างเรียบร้อยดีควรแสดงผลลัพธ์ต่อไปนี้ -
ขั้นตอนที่ 4 - ตั้งค่า Spring Framework Libraries
ตอนนี้ถ้าทุกอย่างเรียบร้อยคุณสามารถดำเนินการตั้งค่า Spring framework ของคุณได้ ต่อไปนี้เป็นขั้นตอนง่ายๆในการดาวน์โหลดและติดตั้งเฟรมเวิร์กบนเครื่องของคุณ
เลือกว่าคุณต้องการติดตั้ง Spring บน Windows หรือ Unix จากนั้นทำตามขั้นตอนต่อไปเพื่อดาวน์โหลดไฟล์. zip สำหรับ Windows และไฟล์. tz สำหรับ Unix
ดาวน์โหลดเวอร์ชันล่าสุดของ Spring framework binaries จาก https://repo.spring.io/release/org/springframework/spring.
ในช่วงเวลาของการพัฒนาบทช่วยสอนนี้ spring-framework-4.1.6.RELEASE-dist.zipถูกดาวน์โหลดบนเครื่อง Windows หลังจากคลายซิปไฟล์ที่ดาวน์โหลดแล้วจะมีโครงสร้างไดเร็กทอรีต่อไปนี้ภายใน E: \ spring
คุณจะพบไลบรารี Spring ทั้งหมดในไดเร็กทอรี E:\spring\libs. ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าตัวแปร CLASSPATH บนไดเร็กทอรีนี้อย่างถูกต้องมิฉะนั้นคุณจะประสบปัญหาขณะเรียกใช้แอปพลิเคชันของคุณ หากคุณใช้ Eclipse คุณไม่จำเป็นต้องตั้งค่า CLASSPATH เนื่องจากการตั้งค่าทั้งหมดจะดำเนินการผ่าน Eclipse
เมื่อคุณทำขั้นตอนสุดท้ายนี้เสร็จแล้วคุณก็พร้อมที่จะไปยัง Spring Example แรกของคุณในบทถัดไป
ให้เราเริ่มการเขียนโปรแกรมจริงด้วย Spring Framework ก่อนที่คุณจะเริ่มเขียนตัวอย่างแรกโดยใช้ Spring framework คุณต้องแน่ใจว่าคุณได้ตั้งค่าสภาพแวดล้อม Spring อย่างถูกต้องตามที่อธิบายไว้ในSpring - Environment Setup Chapter นอกจากนี้เรายังถือว่าคุณมีความรู้เกี่ยวกับ Eclipse IDE เล็กน้อย
ตอนนี้ให้เราดำเนินการเขียนแอปพลิเคชัน Spring อย่างง่ายซึ่งจะพิมพ์คำว่า "Hello World!" หรือข้อความอื่น ๆ ตามการกำหนดค่าที่ทำในไฟล์ Spring Beans Configuration
ขั้นตอนที่ 1 - สร้างโครงการ Java
ขั้นตอนแรกคือการสร้าง Java Project อย่างง่ายโดยใช้ Eclipse IDE ทำตามตัวเลือกFile → New → Project และสุดท้ายเลือก Java Projectตัวช่วยสร้างจากรายการตัวช่วยสร้าง ตอนนี้ตั้งชื่อโครงการของคุณเป็นHelloSpring โดยใช้หน้าต่างตัวช่วยสร้างดังนี้ -
เมื่อสร้างโครงการของคุณสำเร็จคุณจะมีเนื้อหาต่อไปนี้ในไฟล์ Project Explorer -
ขั้นตอนที่ 2 - เพิ่มไลบรารีที่ต้องการ
ขั้นตอนที่สองให้เราเพิ่ม Spring Framework และไลบรารี API การบันทึกทั่วไปในโครงการของเรา ในการดำเนินการนี้ให้คลิกขวาที่ชื่อโครงการของคุณHelloSpring จากนั้นทำตามตัวเลือกต่อไปนี้ที่มีอยู่ในเมนูบริบท - Build Path → Configure Build Path เพื่อแสดงหน้าต่าง Java Build Path ดังนี้ -
ตอนนี้ใช้ Add External JARs อยู่ใต้ปุ่ม Libraries เพื่อเพิ่ม JAR หลักต่อไปนี้จาก Spring Framework และไดเร็กทอรีการติดตั้ง Common Logging -
commons-logging-1.1.1
spring-aop-4.1.6.RELEASE
spring-aspects-4.1.6.RELEASE
spring-beans-4.1.6.RELEASE
spring-context-4.1.6.RELEASE
spring-context-support-4.1.6.RELEASE
spring-core-4.1.6.RELEASE
spring-expression-4.1.6.RELEASE
spring-instrument-4.1.6.RELEASE
spring-instrument-tomcat-4.1.6.RELEASE
spring-jdbc-4.1.6.RELEASE
spring-jms-4.1.6.RELEASE
spring-messaging-4.1.6.RELEASE
spring-orm-4.1.6.RELEASE
spring-oxm-4.1.6.RELEASE
spring-test-4.1.6.RELEASE
spring-tx-4.1.6.RELEASE
spring-web-4.1.6.RELEASE
spring-webmvc-4.1.6.RELEASE
spring-webmvc-portlet-4.1.6.RELEASE
spring-websocket-4.1.6.RELEASE
ขั้นตอนที่ 3 - สร้างไฟล์ต้นฉบับ
ตอนนี้ให้เราสร้างไฟล์ต้นฉบับจริงภายใต้ไฟล์ HelloSpringโครงการ. ก่อนอื่นเราต้องสร้างแพ็คเกจที่เรียกว่าcom.tutorialspoint. โดยคลิกขวาที่src ในส่วน package explorer และทำตามตัวเลือก - New → Package.
ต่อไปเราจะสร้าง HelloWorld.java และ MainApp.java ไฟล์ภายใต้แพ็คเกจ com.tutorialspoint
นี่คือเนื้อหาของ HelloWorld.java ไฟล์ -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ที่สอง MainApp.java -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
ต่อไปนี้เป็นประเด็นสำคัญสองประการเกี่ยวกับโปรแกรมหลัก -
ขั้นตอนแรกคือการสร้างบริบทของแอปพลิเคชันที่เราใช้ Framework API ClassPathXmlApplicationContext(). API นี้โหลดไฟล์คอนฟิกูเรชัน bean และในที่สุดก็ขึ้นอยู่กับ API ที่ให้มาโดยจะดูแลการสร้างและเตรียมใช้งานอ็อบเจ็กต์ทั้งหมดเช่น bean ที่กล่าวถึงในไฟล์คอนฟิกูเรชัน
ขั้นตอนที่สองใช้เพื่อรับถั่วที่ต้องการโดยใช้ getBean()วิธีการของบริบทที่สร้างขึ้น วิธีนี้ใช้ bean ID เพื่อส่งคืนอ็อบเจ็กต์ทั่วไปซึ่งในที่สุดก็สามารถส่งไปยังอ็อบเจ็กต์จริงได้ เมื่อคุณมีอ็อบเจ็กต์คุณสามารถใช้อ็อบเจ็กต์นี้เพื่อเรียกใช้เมธอดคลาสใดก็ได้
ขั้นตอนที่ 4 - สร้างไฟล์การกำหนดค่า Bean
คุณต้องสร้างไฟล์ Bean Configuration ซึ่งเป็นไฟล์ XML และทำหน้าที่เป็นซีเมนต์ที่ยึดเมล็ดถั่วนั่นคือคลาสเข้าด้วยกัน ไฟล์นี้ต้องสร้างภายใต้ไฟล์src ไดเรกทอรีดังที่แสดงในภาพหน้าจอต่อไปนี้ -
โดยปกตินักพัฒนาจะตั้งชื่อไฟล์นี้ว่า Beans.xmlแต่คุณมีอิสระในการเลือกชื่อที่คุณต้องการ คุณต้องตรวจสอบให้แน่ใจว่าไฟล์นี้มีอยู่ใน CLASSPATH และใช้ชื่อเดียวกันในแอปพลิเคชันหลักในขณะที่สร้างบริบทของแอปพลิเคชันดังที่แสดงในไฟล์ MainApp.java
Beans.xml ใช้เพื่อกำหนด ID ที่ไม่ซ้ำกันให้กับ bean ที่แตกต่างกันและเพื่อควบคุมการสร้างอ็อบเจ็กต์ที่มีค่าต่างกันโดยไม่ส่งผลกระทบต่อไฟล์ซอร์ส Spring ใด ๆ ตัวอย่างเช่นการใช้ไฟล์ต่อไปนี้คุณสามารถส่งผ่านค่าใด ๆ สำหรับตัวแปร "ข้อความ" และคุณสามารถพิมพ์ค่าต่างๆของข้อความได้โดยไม่ส่งผลกระทบต่อไฟล์ HelloWorld.java และ MainApp.java ให้เราดูว่ามันทำงานอย่างไร -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
เมื่อแอปพลิเคชัน Spring ถูกโหลดลงในหน่วยความจำ Framework จะใช้ไฟล์คอนฟิกูเรชันด้านบนเพื่อสร้าง bean ทั้งหมดที่กำหนดและกำหนด ID เฉพาะตามที่กำหนดไว้ใน <bean>แท็ก คุณสามารถใช้ได้<property> แท็กเพื่อส่งผ่านค่าของตัวแปรต่างๆที่ใช้ในขณะสร้างออบเจ็กต์
ขั้นตอนที่ 5 - เรียกใช้โปรแกรม
เมื่อคุณสร้างไฟล์คอนฟิกของซอร์สและบีนเสร็จแล้วคุณก็พร้อมสำหรับขั้นตอนนี้ซึ่งกำลังรวบรวมและรันโปรแกรมของคุณ โดยให้แท็บไฟล์ MainApp.Java ทำงานอยู่และใช้อย่างใดอย่างหนึ่งRun ตัวเลือกที่มีอยู่ใน Eclipse IDE หรือใช้ Ctrl + F11 เพื่อรวบรวมและเรียกใช้ไฟล์ MainAppใบสมัคร หากทุกอย่างเรียบร้อยกับแอปพลิเคชันของคุณสิ่งนี้จะพิมพ์ข้อความต่อไปนี้ในคอนโซลของ Eclipse IDE -
Your Message : Hello World!
ขอแสดงความยินดีคุณได้สร้างแอปพลิเคชัน Spring แรกของคุณสำเร็จแล้ว คุณสามารถดูความยืดหยุ่นของแอปพลิเคชัน Spring ข้างต้นได้โดยเปลี่ยนค่าคุณสมบัติ "ข้อความ" และทำให้ไฟล์ต้นฉบับทั้งสองไฟล์ไม่เปลี่ยนแปลง
Spring container เป็นแกนหลักของ Spring Framework คอนเทนเนอร์จะสร้างวัตถุเชื่อมต่อเข้าด้วยกันกำหนดค่าและจัดการวงจรชีวิตที่สมบูรณ์ตั้งแต่การสร้างจนถึงการทำลายล้าง Spring container ใช้ DI เพื่อจัดการส่วนประกอบที่ประกอบขึ้นเป็นแอปพลิเคชัน วัตถุเหล่านี้เรียกว่า Spring Beans ซึ่งเราจะกล่าวถึงในบทต่อไป
คอนเทนเนอร์ได้รับคำแนะนำเกี่ยวกับวัตถุที่จะสร้างอินสแตนซ์กำหนดค่าและประกอบโดยอ่านข้อมูลเมตาของการกำหนดค่าที่มีให้ ข้อมูลเมตาของคอนฟิกูเรชันสามารถแสดงด้วย XML, คำอธิบายประกอบ Java หรือโค้ด Java แผนภาพต่อไปนี้แสดงถึงมุมมองระดับสูงเกี่ยวกับวิธีการทำงานของ Spring คอนเทนเนอร์ Spring IoC ใช้ประโยชน์จากคลาส Java POJO และข้อมูลเมตาของคอนฟิกูเรชันเพื่อสร้างระบบหรือแอ็พพลิเคชันที่กำหนดค่าและเรียกใช้งานได้อย่างสมบูรณ์
Spring มีภาชนะที่แตกต่างกันสองประเภทดังต่อไปนี้
ซีเนียร์ | คอนเทนเนอร์และคำอธิบาย |
---|---|
1 | Spring BeanFactory คอนเทนเนอร์ นี่คือคอนเทนเนอร์ที่ง่ายที่สุดที่ให้การสนับสนุนพื้นฐานสำหรับ DI และกำหนดโดยอินเทอร์เฟซorg.springframework.beans.factory BeanFactory BeanFactory และอินเทอร์เฟซที่เกี่ยวข้องเช่น BeanFactoryAware, InitializingBean, DisposableBean ยังคงมีอยู่ใน Spring เพื่อจุดประสงค์ในการใช้งานร่วมกันได้ย้อนหลังกับเฟรมเวิร์กของบุคคลที่สามจำนวนมากที่ทำงานร่วมกับ Spring |
2 | Spring ApplicationContext Container คอนเทนเนอร์นี้เพิ่มฟังก์ชันการทำงานเฉพาะขององค์กรเช่นความสามารถในการแก้ไขข้อความจากไฟล์คุณสมบัติและความสามารถในการเผยแพร่เหตุการณ์ของแอปพลิเคชันไปยังผู้ฟังเหตุการณ์ที่สนใจ คอนเทนเนอร์นี้ถูกกำหนดโดยอินเตอร์เฟสorg.springframework.context.ApplicationContext |
ApplicationContextภาชนะที่มีฟังก์ชันการทำงานทั้งหมดของBeanFactoryภาชนะจึงแนะนำโดยทั่วไปมากกว่าBeanFactory BeanFactory ยังคงสามารถใช้กับแอปพลิเคชันที่มีน้ำหนักเบาเช่นอุปกรณ์เคลื่อนที่หรือแอปพลิเคชันที่ใช้แอพเพล็ตซึ่งปริมาณข้อมูลและความเร็วมีความสำคัญ
เรียกว่าอ็อบเจ็กต์ที่เป็นกระดูกสันหลังของแอปพลิเคชันของคุณและถูกจัดการโดยคอนเทนเนอร์ Spring IoC beans. ถั่วเป็นวัตถุที่สร้างอินสแตนซ์ประกอบและจัดการโดยคอนเทนเนอร์ Spring IoC ถั่วเหล่านี้สร้างขึ้นด้วยข้อมูลเมตาการกำหนดค่าที่คุณจัดหาให้กับคอนเทนเนอร์ ตัวอย่างเช่นในรูปแบบของนิยาม XML <bean /> ซึ่งคุณได้เห็นไปแล้วในบทก่อนหน้า
คำจำกัดความของถั่วมีข้อมูลที่เรียกว่า configuration metadataซึ่งจำเป็นสำหรับคอนเทนเนอร์ที่จะทราบสิ่งต่อไปนี้ -
- วิธีการสร้างถั่ว
- รายละเอียดวงจรชีวิตของ Bean
- การพึ่งพาของถั่ว
ข้อมูลเมตาของคอนฟิกูเรชันข้างต้นทั้งหมดแปลเป็นชุดของคุณสมบัติต่อไปนี้ที่ประกอบกันเป็นคำนิยาม bean แต่ละตัว
ซีเนียร์ | คุณสมบัติและคำอธิบาย |
---|---|
1 | class แอ็ตทริบิวต์นี้จำเป็นและระบุคลาส bean ที่จะใช้ในการสร้าง bean |
2 | name แอ็ตทริบิวต์นี้ระบุตัวระบุ bean โดยไม่ซ้ำกัน ในข้อมูลเมตาของคอนฟิกูเรชัน XMLbased คุณใช้แอตทริบิวต์ id และ / หรือ name เพื่อระบุ bean identifier (s) |
3 | scope แอ็ตทริบิวต์นี้ระบุขอบเขตของอ็อบเจ็กต์ที่สร้างจากนิยามบีนโดยเฉพาะและจะกล่าวถึงในบทบีนสโคป |
4 | constructor-arg สิ่งนี้ใช้เพื่อฉีดการอ้างอิงและจะกล่าวถึงในบทต่อ ๆ ไป |
5 | properties สิ่งนี้ใช้เพื่อฉีดการอ้างอิงและจะกล่าวถึงในบทต่อ ๆ ไป |
6 | autowiring mode สิ่งนี้ใช้เพื่อฉีดการอ้างอิงและจะกล่าวถึงในบทต่อ ๆ ไป |
7 | lazy-initialization mode lazy-initialized bean บอกให้คอนเทนเนอร์ IoC สร้างอินสแตนซ์ bean เมื่อถูกร้องขอครั้งแรกแทนที่จะเป็นตอนเริ่มต้น |
8 | initialization method การเรียกกลับที่จะเรียกหลังจากที่คอนเทนเนอร์กำหนดคุณสมบัติที่จำเป็นทั้งหมดบนถั่วแล้ว จะกล่าวถึงในบทวงจรชีวิตของถั่ว |
9 | destruction method การเรียกกลับที่จะใช้เมื่อภาชนะที่มีถั่วถูกทำลาย จะกล่าวถึงในบทวงจรชีวิตของถั่ว |
ข้อมูลเมตาการกำหนดค่า Spring
คอนเทนเนอร์ Spring IoC แยกออกจากรูปแบบที่เขียนข้อมูลเมตาการกำหนดค่านี้โดยสิ้นเชิง ต่อไปนี้เป็นวิธีการสำคัญสามวิธีในการจัดเตรียมข้อมูลเมตาของการกำหนดค่าให้กับ Spring Container -
- ไฟล์คอนฟิกูเรชันตาม XML
- การกำหนดค่าตามคำอธิบายประกอบ
- การกำหนดค่าบน Java
คุณได้เห็นแล้วว่ามีการจัดเตรียมข้อมูลเมตาของการกำหนดค่าตาม XML ให้กับคอนเทนเนอร์อย่างไร แต่ขอให้เราดูตัวอย่างไฟล์คอนฟิกูเรชันแบบ XML อื่นที่มีคำจำกัดความ bean ที่แตกต่างกันรวมถึงการเริ่มต้นแบบขี้เกียจวิธีการเริ่มต้นและวิธีการทำลาย -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- A simple bean definition -->
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with lazy init set on -->
<bean id = "..." class = "..." lazy-init = "true">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with initialization method -->
<bean id = "..." class = "..." init-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with destruction method -->
<bean id = "..." class = "..." destroy-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
คุณสามารถตรวจสอบตัวอย่าง Spring Hello Worldเพื่อทำความเข้าใจวิธีกำหนดกำหนดค่าและสร้าง Spring Beans
เราจะพูดคุยเกี่ยวกับ Annotation Based Configuration ในบทที่แยกต่างหาก มีการพูดถึงโดยเจตนาในบทที่แยกต่างหากเนื่องจากเราต้องการให้คุณเข้าใจแนวคิด Spring ที่สำคัญอื่น ๆ อีกสองสามข้อก่อนที่คุณจะเริ่มเขียนโปรแกรมด้วย Spring Dependency Injection พร้อมคำอธิบายประกอบ
เมื่อกำหนด <bean> คุณมีตัวเลือกในการประกาศขอบเขตสำหรับ bean นั้น ตัวอย่างเช่นในการบังคับให้ Spring สร้างอินสแตนซ์ bean ใหม่ทุกครั้งที่ต้องการคุณควรประกาศแอตทริบิวต์ขอบเขตของ bean เป็นprototype. ในทำนองเดียวกันหากคุณต้องการให้ Spring ส่งคืนอินสแตนซ์ bean เดียวกันทุกครั้งที่ต้องการคุณควรประกาศแอตทริบิวต์ขอบเขตของ bean เป็นsingleton.
Spring Framework สนับสนุนขอบเขตห้าขอบเขตต่อไปนี้ซึ่งสามขอบเขตนี้มีให้เฉพาะเมื่อคุณใช้ ApplicationContext ที่รับรู้บนเว็บ
ซีเนียร์ | ขอบเขตและคำอธิบาย |
---|---|
1 | singleton สิ่งนี้กำหนดขอบเขตของคำจำกัดความ bean เป็นอินสแตนซ์เดียวต่อคอนเทนเนอร์ Spring IoC (ค่าเริ่มต้น) |
2 | prototype ขอบเขตนี้กำหนดนิยาม bean เดียวเพื่อให้มีอินสแตนซ์อ็อบเจ็กต์จำนวนเท่าใดก็ได้ |
3 | request สิ่งนี้กำหนดขอบเขตคำจำกัดความ bean ให้กับคำขอ HTTP ใช้ได้เฉพาะในบริบทของ Spring ApplicationContext ที่รับรู้บนเว็บ |
4 | session สิ่งนี้กำหนดขอบเขตนิยาม bean ให้กับเซสชัน HTTP ใช้ได้เฉพาะในบริบทของ Spring ApplicationContext ที่รับรู้บนเว็บ |
5 | global-session สิ่งนี้กำหนดขอบเขตคำจำกัดความของ bean ให้กับเซสชัน HTTP ส่วนกลาง ใช้ได้เฉพาะในบริบทของ Spring ApplicationContext ที่รับรู้บนเว็บ |
ในบทนี้เราจะพูดถึงสองขอบเขตแรกและอีกสามขอบเขตที่เหลือจะกล่าวถึงเมื่อเราพูดถึง Spring ApplicationContext ที่รับรู้บนเว็บ
ขอบเขตซิงเกิลตัน
หากขอบเขตถูกตั้งค่าเป็นซิงเกิลตันคอนเทนเนอร์ Spring IoC จะสร้างอินสแตนซ์ของอ็อบเจ็กต์ที่กำหนดโดยนิยาม bean นั้น อินสแตนซ์เดียวนี้ถูกเก็บไว้ในแคชของถั่วเดี่ยวดังกล่าวและคำขอและการอ้างอิงที่ตามมาทั้งหมดสำหรับ bean ที่มีชื่อจะส่งคืนอ็อบเจ็กต์ที่แคช
ขอบเขตเริ่มต้นคือซิงเกิลตันเสมอ อย่างไรก็ตามเมื่อคุณต้องการถั่วเพียงหนึ่งอินสแตนซ์คุณสามารถตั้งค่าไฟล์scope คุณสมบัติถึง singleton ในไฟล์คอนฟิกูเรชัน bean ดังที่แสดงในข้อมูลโค้ดต่อไปนี้ -
<!-- A bean definition with singleton scope -->
<bean id = "..." class = "..." scope = "singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorldและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์ -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.setMessage("I'm object A");
objA.getMessage();
HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml จำเป็นสำหรับขอบเขตซิงเกิลตัน -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "singleton">
</bean>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
Your Message : I'm object A
Your Message : I'm object A
ขอบเขตต้นแบบ
ถ้าขอบเขตถูกตั้งค่าเป็นต้นแบบคอนเทนเนอร์ Spring IoC จะสร้างอินสแตนซ์ bean ใหม่ของอ็อบเจ็กต์ทุกครั้งที่มีการร้องขอสำหรับ bean เฉพาะนั้น ตามกฎแล้วให้ใช้ขอบเขตต้นแบบสำหรับเมล็ดถั่วที่เต็มสถานะทั้งหมดและขอบเขตซิงเกิลตันสำหรับถั่วไร้สัญชาติ
ในการกำหนดขอบเขตต้นแบบคุณสามารถตั้งค่า scope คุณสมบัติถึง prototype ในไฟล์คอนฟิกูเรชัน bean ดังที่แสดงในข้อมูลโค้ดต่อไปนี้ -
<!-- A bean definition with prototype scope -->
<bean id = "..." class = "..." scope = "prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorldและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.setMessage("I'm object A");
objA.getMessage();
HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml จำเป็นสำหรับขอบเขตต้นแบบ -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "prototype">
</bean>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
Your Message : I'm object A
Your Message : null
วงจรชีวิตของถั่วสปริงนั้นเข้าใจง่าย เมื่อถั่วถูกสร้างอินสแตนซ์อาจจำเป็นต้องทำการเริ่มต้นบางอย่างเพื่อให้มันอยู่ในสถานะที่ใช้งานได้ ในทำนองเดียวกันเมื่อไม่จำเป็นต้องใช้ถั่วอีกต่อไปและถูกนำออกจากภาชนะอาจต้องมีการล้างข้อมูลบางอย่าง
แม้ว่าจะมีรายการกิจกรรมที่เกิดขึ้นเบื้องหลังระหว่างช่วงเวลาของการสร้างอินสแตนซ์ของถั่วและการทำลายล้างบทนี้จะกล่าวถึงวิธีการเรียกกลับวงจรชีวิตของถั่วที่สำคัญเพียงสองวิธีซึ่งจำเป็นในช่วงเวลาของการเริ่มต้นถั่วและการทำลายมัน
ในการกำหนดการตั้งค่าและการแยกย่อยสำหรับ bean เราเพียงแค่ประกาศ <bean> ด้วย initmethod และ / หรือ destroy-methodพารามิเตอร์ แอตทริบิวต์ init-method ระบุเมธอดที่จะเรียกใช้บน bean ทันทีที่สร้างอินสแตนซ์ ในทำนองเดียวกัน destroymethod ระบุวิธีการที่เรียกก่อนที่ถั่วจะถูกลบออกจากคอนเทนเนอร์
การเรียกกลับการเริ่มต้น
อินเทอร์เฟซ org.springframework.beans.factoryInitializingBean ระบุวิธีการเดียว -
void afterPropertiesSet() throws Exception;
ดังนั้นคุณสามารถใช้อินเทอร์เฟซด้านบนและงานเริ่มต้นสามารถทำได้ภายในเมธอด afterPropertiesSet () ดังนี้ -
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
ในกรณีของข้อมูลเมตาของคอนฟิกูเรชัน XML คุณสามารถใช้ไฟล์ init-methodแอตทริบิวต์เพื่อระบุชื่อของเมธอดที่มีลายเซ็นไม่มีอาร์กิวเมนต์เป็นโมฆะ ตัวอย่างเช่น -
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
ต่อไปนี้เป็นคำจำกัดความของคลาส -
public class ExampleBean {
public void init() {
// do some initialization work
}
}
การเรียกกลับการทำลายล้าง
org.springframework.beans.factory.DisposableBeanอินเตอร์เฟซที่ระบุวิธีการเดียว -
void destroy() throws Exception;
ดังนั้นคุณสามารถใช้อินเทอร์เฟซด้านบนและงานสุดท้ายสามารถทำได้ภายในวิธีการ destroy () ดังนี้ -
public class ExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}
ในกรณีของข้อมูลเมตาของคอนฟิกูเรชัน XML คุณสามารถใช้ไฟล์ destroy-methodแอตทริบิวต์เพื่อระบุชื่อของเมธอดที่มีลายเซ็นไม่มีอาร์กิวเมนต์เป็นโมฆะ ตัวอย่างเช่น -
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
ต่อไปนี้เป็นคำจำกัดความของคลาส -
public class ExampleBean {
public void destroy() {
// do some destruction work
}
}
หากคุณใช้คอนเทนเนอร์ IoC ของ Spring ในสภาพแวดล้อมที่ไม่ใช่เว็บแอปพลิเคชัน ตัวอย่างเช่นในสภาพแวดล้อมเดสก์ท็อปไคลเอ็นต์ที่สมบูรณ์คุณลงทะเบียน hook การปิดระบบกับ JVM การทำเช่นนี้ช่วยให้มั่นใจได้ว่าการปิดเครื่องจะเป็นไปอย่างราบรื่นและเรียกใช้เมธอดการทำลายที่เกี่ยวข้องกับถั่วเดี่ยวของคุณเพื่อให้ทรัพยากรทั้งหมดถูกปลดปล่อย
ขอแนะนำว่าอย่าใช้การเรียกกลับ InitializingBean หรือ DisposableBean เนื่องจากการกำหนดค่า XML ให้ความยืดหยุ่นมากในแง่ของการตั้งชื่อวิธีการของคุณ
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorldและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์ -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy() {
System.out.println("Bean will destroy now.");
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.javaไฟล์. ที่นี่คุณต้องลงทะเบียน hook การปิดระบบregisterShutdownHook()วิธีการที่ประกาศบนคลาส AbstractApplicationContext วิธีนี้จะช่วยให้มั่นใจได้ว่าการปิดเครื่องจะเป็นไปอย่างราบรื่นและเรียกใช้วิธีการทำลายที่เกี่ยวข้อง
package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
context.registerShutdownHook();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml จำเป็นสำหรับวิธีการเริ่มต้นและทำลาย -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" init-method = "init"
destroy-method = "destroy">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
Bean is going through init.
Your Message : Hello World!
Bean will destroy now.
วิธีการเริ่มต้นเริ่มต้นและทำลาย
หากคุณมีถั่วมากเกินไปที่มีการเริ่มต้นและ / หรือทำลายวิธีการที่มีชื่อเดียวกันคุณไม่จำเป็นต้องประกาศ init-method และ destroy-methodในแต่ละถั่ว แต่กรอบงานให้ความยืดหยุ่นในการกำหนดค่าสถานการณ์ดังกล่าวโดยใช้default-init-method และ default-destroy-method แอตทริบิวต์ขององค์ประกอบ <beans> ดังต่อไปนี้ -
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-init-method = "init"
default-destroy-method = "destroy">
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
BeanPostProcessor อินเทอร์เฟซกำหนดวิธีการโทรกลับที่คุณสามารถนำไปใช้เพื่อจัดเตรียมลอจิกการสร้างอินสแตนซ์ของคุณเองตรรกะการแก้ปัญหาการอ้างอิง ฯลฯ นอกจากนี้คุณยังสามารถใช้ตรรกะที่กำหนดเองบางอย่างได้หลังจากที่คอนเทนเนอร์ Spring เสร็จสิ้นการสร้างอินสแตนซ์การกำหนดค่าและการเริ่มต้น Bean โดยการเสียบการใช้งาน BeanPostProcessor .
คุณสามารถกำหนดค่าอินเทอร์เฟซ BeanPostProcessor หลายรายการและคุณสามารถควบคุมลำดับที่อินเทอร์เฟซ BeanPostProcessor เหล่านี้ดำเนินการได้โดยการตั้งค่า order คุณสมบัติที่ให้ BeanPostProcessor ดำเนินการ Ordered อินเตอร์เฟซ.
BeanPostProcessors ทำงานบนอินสแตนซ์ bean (หรืออ็อบเจ็กต์) ซึ่งหมายความว่าคอนเทนเนอร์ Spring IoC สร้างอินสแตนซ์อินสแตนซ์ bean จากนั้นอินเทอร์เฟซ BeanPostProcessor จะทำงาน
อัน ApplicationContext ตรวจจับถั่วใด ๆ โดยอัตโนมัติที่กำหนดด้วยการใช้งานไฟล์ BeanPostProcessor อินเทอร์เฟซและรีจิสเตอร์ถั่วเหล่านี้เป็นตัวประมวลผลภายหลังที่จะเรียกใช้อย่างเหมาะสมโดยคอนเทนเนอร์เมื่อสร้างถั่ว
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงวิธีการเขียนลงทะเบียนและใช้ BeanPostProcessors ในบริบทของ ApplicationContext
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorld , InitHelloWorldและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์ -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy(){
System.out.println("Bean will destroy now.");
}
}
นี่เป็นตัวอย่างพื้นฐานของการใช้ BeanPostProcessor ซึ่งพิมพ์ชื่อ bean ก่อนและหลังการกำหนดค่าเริ่มต้นของ bean ใด ๆ คุณสามารถใช้ตรรกะที่ซับซ้อนมากขึ้นก่อนและหลังการใส่ถั่วได้เนื่องจากคุณสามารถเข้าถึงอ็อบเจ็กต์ bean ได้ทั้งในวิธีการโพสต์โปรเซสเซอร์
นี่คือเนื้อหาของ InitHelloWorld.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.javaไฟล์. ที่นี่คุณต้องลงทะเบียน hook การปิดระบบregisterShutdownHook()วิธีการที่ประกาศบนคลาส AbstractApplicationContext สิ่งนี้จะช่วยให้มั่นใจได้ว่าการปิดเครื่องเป็นไปอย่างราบรื่นและเรียกใช้วิธีการทำลายที่เกี่ยวข้อง
package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
context.registerShutdownHook();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml จำเป็นสำหรับวิธีการเริ่มต้นและทำลาย -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"
init-method = "init" destroy-method = "destroy">
<property name = "message" value = "Hello World!"/>
</bean>
<bean class = "com.tutorialspoint.InitHelloWorld" />
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
BeforeInitialization : helloWorld
Bean is going through init.
AfterInitialization : helloWorld
Your Message : Hello World!
Bean will destroy now.
นิยาม bean สามารถมีข้อมูลคอนฟิกูเรชันจำนวนมากรวมถึงอาร์กิวเมนต์ตัวสร้างค่าคุณสมบัติและข้อมูลจำเพาะของคอนเทนเนอร์เช่นวิธีการเริ่มต้นชื่อเมธอดโรงงานแบบคงที่และอื่น ๆ
นิยาม child bean สืบทอดข้อมูลคอนฟิกูเรชันจากนิยามพาเรนต์ นิยามลูกสามารถแทนที่ค่าบางค่าหรือเพิ่มค่าอื่น ๆ ได้ตามต้องการ
การสืบทอดนิยาม Spring Bean ไม่มีส่วนเกี่ยวข้องกับการสืบทอดคลาส Java แต่แนวคิดการสืบทอดนั้นเหมือนกัน คุณสามารถกำหนดนิยาม parent bean เป็นเทมเพลตและ child bean อื่น ๆ สามารถสืบทอดคอนฟิกูเรชันที่ต้องการจาก parent bean
เมื่อคุณใช้ข้อมูลเมตาของคอนฟิกูเรชันแบบ XML คุณระบุนิยามลูกบีนโดยใช้ parent แอตทริบิวต์ระบุถั่วแม่เป็นค่าของแอตทริบิวต์นี้
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorld , HelloIndiaและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xmlที่เรากำหนดไว้ "helloWorld" ถั่วซึ่งมีสองคุณสมบัติmessage1และmessage2 ถั่ว "helloIndia" ถัดไปถูกกำหนดให้เป็นลูกของถั่ว "helloWorld" โดยใช้parentแอตทริบิวต์ เด็กถั่วสืบทอดmessage2คุณสมบัติตามที่เป็นอยู่และการแทนที่message1ทรัพย์สินและแนะนำอีกหนึ่งคุณสมบัติmessage3
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message1" value = "Hello World!"/>
<property name = "message2" value = "Hello Second World!"/>
</bean>
<bean id ="helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld">
<property name = "message1" value = "Hello India!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
</beans>
นี่คือเนื้อหาของ HelloWorld.java ไฟล์ -
package com.tutorialspoint;
public class HelloWorld {
private String message1;
private String message2;
public void setMessage1(String message){
this.message1 = message;
}
public void setMessage2(String message){
this.message2 = message;
}
public void getMessage1(){
System.out.println("World Message1 : " + message1);
}
public void getMessage2(){
System.out.println("World Message2 : " + message2);
}
}
นี่คือเนื้อหาของ HelloIndia.java ไฟล์ -
package com.tutorialspoint;
public class HelloIndia {
private String message1;
private String message2;
private String message3;
public void setMessage1(String message){
this.message1 = message;
}
public void setMessage2(String message){
this.message2 = message;
}
public void setMessage3(String message){
this.message3 = message;
}
public void getMessage1(){
System.out.println("India Message1 : " + message1);
}
public void getMessage2(){
System.out.println("India Message2 : " + message2);
}
public void getMessage3(){
System.out.println("India Message3 : " + message3);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.getMessage1();
objA.getMessage2();
HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
objB.getMessage1();
objB.getMessage2();
objB.getMessage3();
}
}
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!
หากคุณสังเกตที่นี่เราไม่ได้ส่งข้อความ 2 ในขณะที่สร้าง "helloIndia" bean แต่มันผ่านไปได้เพราะการสืบทอดความหมายของถั่ว
เทมเพลตคำจำกัดความของถั่ว
คุณสามารถสร้างเทมเพลตคำจำกัดความ Bean ซึ่งสามารถใช้โดยคำจำกัดความลูกถั่วอื่น ๆ ได้โดยไม่ต้องออกแรงมาก ในขณะที่กำหนด Bean Definition Template คุณไม่ควรระบุไฟล์class แอตทริบิวต์และควรระบุ abstract แอตทริบิวต์และควรระบุแอตทริบิวต์นามธรรมด้วยค่า true ดังแสดงในข้อมูลโค้ดต่อไปนี้ -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "beanTeamplate" abstract = "true">
<property name = "message1" value = "Hello World!"/>
<property name = "message2" value = "Hello Second World!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
<bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">
<property name = "message1" value = "Hello India!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
</beans>
ถั่วผู้ปกครองไม่สามารถ instantiated ในตัวเองเพราะมันเป็นที่ไม่สมบูรณ์และยังมีการทำเครื่องหมายอย่างชัดเจนเป็นนามธรรม เมื่อคำจำกัดความเป็นนามธรรมเช่นนี้จะใช้ได้เฉพาะในฐานะนิยามแม่แบบบีนบริสุทธิ์ที่ทำหน้าที่เป็นคำจำกัดความหลักสำหรับนิยามลูก
แอปพลิเคชันที่ใช้ Java ทุกตัวมีออบเจ็กต์สองสามชิ้นที่ทำงานร่วมกันเพื่อนำเสนอสิ่งที่ผู้ใช้ปลายทางเห็นว่าเป็นแอปพลิเคชันที่ใช้งานได้ เมื่อเขียนแอ็พพลิเคชัน Java ที่ซับซ้อนคลาสแอ็พพลิเคชันควรเป็นอิสระจากคลาส Java อื่น ๆ ให้มากที่สุดเพื่อเพิ่มความเป็นไปได้ในการนำคลาสเหล่านี้กลับมาใช้ใหม่และทดสอบโดยไม่ขึ้นกับคลาสอื่น ๆ ในขณะทดสอบยูนิต Dependency Injection (หรือบางครั้งเรียกว่าการเดินสาย) ช่วยในการเชื่อมคลาสเหล่านี้เข้าด้วยกันและในขณะเดียวกันก็ทำให้พวกเขาเป็นอิสระ
พิจารณาว่าคุณมีแอปพลิเคชันที่มีส่วนประกอบของโปรแกรมแก้ไขข้อความและคุณต้องการตรวจสอบการสะกด รหัสมาตรฐานของคุณจะมีลักษณะดังนี้ -
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
}
สิ่งที่เราทำที่นี่คือสร้างการพึ่งพาระหว่าง TextEditor และ SpellChecker ในสถานการณ์การควบคุมที่ผกผันเราจะทำสิ่งนี้แทน -
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
ที่นี่ TextEditor ไม่ควรกังวลเกี่ยวกับการใช้งาน SpellChecker SpellChecker จะดำเนินการโดยอิสระและจะถูกส่งไปยัง TextEditor ในช่วงเวลาของการสร้างอินสแตนซ์ TextEditor ขั้นตอนทั้งหมดนี้ควบคุมโดย Spring Framework
ที่นี่เราได้ลบการควบคุมทั้งหมดออกจาก TextEditor และเก็บไว้ที่อื่น (เช่นไฟล์คอนฟิกูเรชัน XML) และการอ้างอิง (เช่นคลาส SpellChecker) จะถูกแทรกเข้าไปในคลาส TextEditor ผ่าน Class Constructor. ดังนั้นขั้นตอนการควบคุมจึงถูก "กลับด้าน" โดย Dependency Injection (DI) เนื่องจากคุณได้มอบหมายการพึ่งพาไปยังระบบภายนอกบางระบบอย่างมีประสิทธิภาพ
วิธีที่สองของการฉีดพึ่งพาคือผ่าน Setter Methodsของคลาส TextEditor ที่เราจะสร้างอินสแตนซ์ SpellChecker อินสแตนซ์นี้จะใช้เพื่อเรียกเมธอด setter เพื่อเริ่มต้นคุณสมบัติของ TextEditor
ดังนั้น DI จึงมีอยู่ในสองตัวแปรหลักและสองบทย่อยต่อไปนี้จะครอบคลุมทั้งสองอย่างด้วยตัวอย่าง -
ซีเนียร์ | ประเภทและคำอธิบายการฉีดขึ้นอยู่กับ |
---|---|
1 | การฉีดขึ้นอยู่กับตัวสร้าง DI ที่ใช้คอนสตรัคเตอร์จะทำได้เมื่อคอนเทนเนอร์เรียกใช้คลาสคอนสตรัคเตอร์พร้อมด้วยอาร์กิวเมนต์จำนวนหนึ่งซึ่งแต่ละตัวแสดงถึงการพึ่งพาคลาสอื่น |
2 | การฉีดขึ้นอยู่กับตัวตั้งค่า DI ที่ใช้ Setter ทำได้โดยเมธอดการเรียกคอนเทนเนอร์บนถั่วของคุณหลังจากเรียกใช้ตัวสร้างที่ไม่มีอาร์กิวเมนต์หรือวิธีโรงงานแบบคงที่ไม่มีอาร์กิวเมนต์เพื่อสร้างอินสแตนซ์ bean ของคุณ |
คุณสามารถผสม DI ทั้งสองแบบ Constructor-based และ Setter-based DI ได้ แต่เป็นกฎง่ายๆในการใช้อาร์กิวเมนต์ตัวสร้างสำหรับการอ้างอิงที่จำเป็นและตัวตั้งค่าสำหรับการอ้างอิงที่เป็นทางเลือก
รหัสมีความสะอาดขึ้นด้วยหลักการ DI และการแยกส่วนจะมีประสิทธิภาพมากขึ้นเมื่อวัตถุมีการอ้างอิง อ็อบเจ็กต์ไม่ค้นหาการอ้างอิงและไม่ทราบตำแหน่งหรือคลาสของการอ้างอิง แต่ทุกอย่างจะได้รับการดูแลโดย Spring Framework
ดังที่คุณทราบว่าคลาสภายในของ Java ถูกกำหนดไว้ภายในขอบเขตของคลาสอื่นในทำนองเดียวกัน inner beansเป็นถั่วที่กำหนดไว้ในขอบเขตของถั่วอื่น ดังนั้นองค์ประกอบ <bean /> ภายในองค์ประกอบ <property /> หรือ <constructor-arg /> จึงเรียกว่า inner bean และแสดงไว้ด้านล่าง
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "outerBean" class = "...">
<property name = "target">
<bean id = "innerBean" class = "..."/>
</property>
</bean>
</beans>
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java TextEditor , SpellCheckerและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ TextEditor.java ไฟล์ -
package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์คลาสอื่น SpellChecker.java -
package com.tutorialspoint;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml ซึ่งมีการกำหนดค่าสำหรับ setter-based injection แต่ใช้ inner beans -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Definition for textEditor bean using inner bean -->
<bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
<property name = "spellChecker">
<bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"/>
</property>
</bean>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.
คุณได้เห็นวิธีกำหนดค่าประเภทข้อมูลดั้งเดิมโดยใช้ value แอตทริบิวต์และการอ้างอิงวัตถุโดยใช้ refแอตทริบิวต์ของแท็ก <property> ในไฟล์คอนฟิกูเรชัน Bean ของคุณ ทั้งสองกรณีจัดการกับการส่งค่าเอกพจน์ไปยังถั่ว
ตอนนี้จะเป็นอย่างไรถ้าคุณต้องการส่งผ่านค่าพหูพจน์เช่น Java Collection types เช่น List, Set, Map และ Properties เพื่อรับมือกับสถานการณ์ Spring มีองค์ประกอบการกำหนดค่าคอลเลกชันสี่ประเภทซึ่งมีดังต่อไปนี้ -
ซีเนียร์ No | องค์ประกอบและคำอธิบาย |
---|---|
1 | <list> สิ่งนี้ช่วยในการเดินสายเช่นการฉีดรายการค่าทำให้รายการซ้ำกัน |
2 | <set> สิ่งนี้ช่วยในการเดินสายชุดของค่า แต่ไม่มีรายการที่ซ้ำกัน |
3 | <map> สิ่งนี้สามารถใช้เพื่อฉีดคอลเลกชันของคู่ชื่อ - ค่าโดยที่ชื่อและค่าสามารถเป็นประเภทใดก็ได้ |
4 | <props> สิ่งนี้สามารถใช้เพื่อฉีดคอลเลกชันของคู่ชื่อ - ค่าโดยที่ชื่อและค่าเป็นทั้งสองสตริง |
คุณสามารถใช้ <list> หรือ <set> เพื่อเชื่อมโยงการใช้งาน java.util.Collection หรือไฟล์ array.
คุณจะเจอสองสถานการณ์ (a) การส่งผ่านค่าโดยตรงของคอลเลกชันและ (b) การส่งการอ้างอิงของ bean เป็นหนึ่งในองค์ประกอบคอลเลกชัน
ตัวอย่าง
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java JavaCollectionและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ JavaCollection.java ไฟล์ -
package com.tutorialspoint;
import java.util.*;
public class JavaCollection {
List addressList;
Set addressSet;
Map addressMap;
Properties addressProp;
// a setter method to set List
public void setAddressList(List addressList) {
this.addressList = addressList;
}
// prints and returns all the elements of the list.
public List getAddressList() {
System.out.println("List Elements :" + addressList);
return addressList;
}
// a setter method to set Set
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
// prints and returns all the elements of the Set.
public Set getAddressSet() {
System.out.println("Set Elements :" + addressSet);
return addressSet;
}
// a setter method to set Map
public void setAddressMap(Map addressMap) {
this.addressMap = addressMap;
}
// prints and returns all the elements of the Map.
public Map getAddressMap() {
System.out.println("Map Elements :" + addressMap);
return addressMap;
}
// a setter method to set Property
public void setAddressProp(Properties addressProp) {
this.addressProp = addressProp;
}
// prints and returns all the elements of the Property.
public Properties getAddressProp() {
System.out.println("Property Elements :" + addressProp);
return addressProp;
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์ -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
JavaCollection jc=(JavaCollection)context.getBean("javaCollection");
jc.getAddressList();
jc.getAddressSet();
jc.getAddressMap();
jc.getAddressProp();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml ซึ่งมีการกำหนดค่าสำหรับคอลเลกชันทุกประเภท -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Definition for javaCollection -->
<bean id = "javaCollection" class = "com.tutorialspoint.JavaCollection">
<!-- results in a setAddressList(java.util.List) call -->
<property name = "addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<!-- results in a setAddressSet(java.util.Set) call -->
<property name = "addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
<!-- results in a setAddressMap(java.util.Map) call -->
<property name = "addressMap">
<map>
<entry key = "1" value = "INDIA"/>
<entry key = "2" value = "Pakistan"/>
<entry key = "3" value = "USA"/>
<entry key = "4" value = "USA"/>
</map>
</property>
<!-- results in a setAddressProp(java.util.Properties) call -->
<property name = "addressProp">
<props>
<prop key = "one">INDIA</prop>
<prop key = "one">INDIA</prop>
<prop key = "two">Pakistan</prop>
<prop key = "three">USA</prop>
<prop key = "four">USA</prop>
</props>
</property>
</bean>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
List Elements :[INDIA, Pakistan, USA, USA]
Set Elements :[INDIA, Pakistan, USA]
ap Elements :{1 = INDIA, 2 = Pakistan, 3 = USA, 4 = USA}
Property Elements :{two = Pakistan, one = INDIA, three = USA, four = USA}
การอ้างอิงการฉีดถั่ว
คำจำกัดความ Bean ต่อไปนี้จะช่วยให้คุณเข้าใจวิธีแทรกการอ้างอิง bean เป็นองค์ประกอบหนึ่งของคอลเล็กชัน แม้กระทั่งคุณสามารถผสมการอ้างอิงและค่าทั้งหมดเข้าด้วยกันดังที่แสดงในข้อมูลโค้ดต่อไปนี้ -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Bean Definition to handle references and values -->
<bean id = "..." class = "...">
<!-- Passing bean reference for java.util.List -->
<property name = "addressList">
<list>
<ref bean = "address1"/>
<ref bean = "address2"/>
<value>Pakistan</value>
</list>
</property>
<!-- Passing bean reference for java.util.Set -->
<property name = "addressSet">
<set>
<ref bean = "address1"/>
<ref bean = "address2"/>
<value>Pakistan</value>
</set>
</property>
<!-- Passing bean reference for java.util.Map -->
<property name = "addressMap">
<map>
<entry key = "one" value = "INDIA"/>
<entry key = "two" value-ref = "address1"/>
<entry key = "three" value-ref = "address2"/>
</map>
</property>
</bean>
</beans>
ในการใช้คำจำกัดความ bean ข้างต้นคุณต้องกำหนดเมธอด setter ของคุณเพื่อให้สามารถจัดการการอ้างอิงได้เช่นกัน
การแทรกค่าสตริงว่างและว่าง
หากคุณต้องการส่งสตริงว่างเป็นค่าคุณสามารถส่งผ่านได้ดังนี้ -
<bean id = "..." class = "exampleBean">
<property name = "email" value = ""/>
</bean>
ตัวอย่างก่อนหน้านี้เทียบเท่ากับโค้ด Java: exampleBean.setEmail ("")
หากคุณต้องการส่งค่า NULL คุณสามารถส่งผ่านได้ดังนี้ -
<bean id = "..." class = "exampleBean">
<property name = "email"><null/></property>
</bean>
ตัวอย่างก่อนหน้านี้เทียบเท่ากับโค้ด Java: exampleBean.setEmail (null)
คุณได้เรียนรู้วิธีการประกาศ bean โดยใช้องค์ประกอบ <bean> และฉีด <bean> โดยใช้องค์ประกอบ <constructor-arg> และ <property> ในไฟล์คอนฟิกูเรชัน XML
ภาชนะสปริงสามารถ autowire ความสัมพันธ์ระหว่างการทำงานร่วมกัน bean โดยไม่ใช้องค์ประกอบ <constructor-arg> และ <property> ซึ่งช่วยลดปริมาณการกำหนดค่า XML ที่คุณเขียนสำหรับแอปพลิเคชันที่ใช้ Spring ขนาดใหญ่
โหมดการเดินสายอัตโนมัติ
ต่อไปนี้เป็นโหมดการเดินสายอัตโนมัติซึ่งสามารถใช้เพื่อสั่งให้ Spring container ใช้การเดินสายอัตโนมัติสำหรับการฉีดขึ้น คุณใช้แอตทริบิวต์ autowire ขององค์ประกอบ <bean /> เพื่อระบุautowire โหมดสำหรับนิยามถั่ว
ซีเนียร์ No | โหมดและคำอธิบาย |
---|---|
1 | no นี่คือการตั้งค่าเริ่มต้นซึ่งหมายความว่าไม่มีการเดินสายอัตโนมัติและคุณควรใช้การอ้างอิงแบบชัดเจนของ bean สำหรับการเดินสาย คุณไม่มีอะไรต้องทำพิเศษสำหรับการเดินสายนี้ นี่คือสิ่งที่คุณได้เห็นแล้วในบท Dependency Injection |
2 | โดยชื่อ การเริ่มอัตโนมัติตามชื่อคุณสมบัติ Spring container ดูคุณสมบัติของ bean ที่มีการตั้งค่าแอตทริบิวต์autowireเป็นbyNameในไฟล์คอนฟิกูเรชัน XML จากนั้นจะพยายามจับคู่และเชื่อมโยงคุณสมบัติกับถั่วที่กำหนดโดยชื่อเดียวกันในไฟล์คอนฟิกูเรชัน |
3 | byType การเริ่มอัตโนมัติตามประเภทข้อมูลคุณสมบัติ Spring container ดูคุณสมบัติของ bean ที่มีการตั้งค่าแอตทริบิวต์autowireเป็นbyTypeในไฟล์คอนฟิกูเรชัน XML จากนั้นจะพยายามจับคู่และวางสายคุณสมบัติหากเป็นtypeตรงกับชื่อ bean อันใดอันหนึ่งในไฟล์คอนฟิกูเรชัน หากมีถั่วมากกว่าหนึ่งเมล็ดจะมีข้อยกเว้นร้ายแรง |
4 | constructor Similar to byType, but type applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised. |
5 | autodetect Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType. |
You can use byType or constructor autowiring mode to wire arrays and other typed-collections.
Limitations with autowiring
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing for developers to use it to wire only one or two bean definitions. Though, autowiring can significantly reduce the need to specify properties or constructor arguments but you should consider the limitations and disadvantages of autowiring before using them.
Sr.No. | Limitations & Description |
---|---|
1 | Overriding possibility You can still specify dependencies using <constructor-arg> and <property> settings which will always override autowiring. |
2 | Primitive data types You cannot autowire so-called simple properties such as primitives, Strings, and Classes. |
3 | Confusing nature Autowiring is less exact than explicit wiring, so if possible prefer using explict wiring. |
Starting from Spring 2.5 it became possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration.
Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.
Annotation wiring is not turned on in the Spring container by default. So, before we can use annotation-based wiring, we will need to enable it in our Spring configuration file. So consider the following configuration file in case you want to use any annotation in your Spring application.
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context = "http://www.springframework.org/schema/context"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
Once <context:annotation-config/> is configured, you can start annotating your code to indicate that Spring should automatically wire values into properties, methods, and constructors. Let us look at a few important annotations to understand how they work −
Sr.No. | Annotation & Description |
---|---|
1 | @Required The @Required annotation applies to bean property setter methods. |
2 | @Autowired The @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties. |
3 | @Qualifier The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired. |
4 | JSR-250 Annotations Spring supports JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations. |
So far you have seen how we configure Spring beans using XML configuration file. If you are comfortable with XML configuration, then it is really not required to learn how to proceed with Java-based configuration as you are going to achieve the same result using either of the configurations available.
Java-based configuration option enables you to write most of your Spring configuration without XML but with the help of few Java-based annotations explained in this chapter.
@Configuration & @Bean Annotations
Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. The simplest possible @Configuration class would be as follows −
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
The above code will be equivalent to the following XML configuration −
<beans>
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" />
</beans>
Here, the method name is annotated with @Bean works as bean ID and it creates and returns the actual bean. Your configuration class can have a declaration for more than one @Bean. Once your configuration classes are defined, you can load and provide them to Spring container using AnnotationConfigApplicationContext as follows −
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
You can load various configuration classes as follows −
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class, OtherConfig.class);
ctx.register(AdditionalConfig.class);
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
Example
Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −
Steps | Description |
---|---|
1 | Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org. |
4 | Create Java classes HelloWorldConfig, HelloWorld and MainApp under the com.tutorialspoint package. |
5 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
Here is the content of HelloWorldConfig.java file
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
Here is the content of HelloWorld.java file
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Following is the content of the MainApp.java file
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
}
Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −
Your Message : Hello World!
Injecting Bean Dependencies
When @Beans have dependencies on one another, expressing that the dependency is as simple as having one bean method calling another as follows −
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}
Here, the foo bean receives a reference to bar via the constructor injection. Now let us look at another working example.
Example
Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −
Steps | Description |
---|---|
1 | Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org. |
4 | Create Java classes TextEditorConfig, TextEditor, SpellChecker and MainApp under the com.tutorialspoint package. |
5 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
Here is the content of TextEditorConfig.java file
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class TextEditorConfig {
@Bean
public TextEditor textEditor(){
return new TextEditor( spellChecker() );
}
@Bean
public SpellChecker spellChecker(){
return new SpellChecker( );
}
}
Here is the content of TextEditor.java file
package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Following is the content of another dependent class file SpellChecker.java
package com.tutorialspoint;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
Following is the content of the MainApp.java file
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(TextEditorConfig.class);
TextEditor te = ctx.getBean(TextEditor.class);
te.spellCheck();
}
}
Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −
Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.
The @Import Annotation
The @Import annotation allows for loading @Bean definitions from another configuration class. Consider a ConfigA class as follows −
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
You can import above Bean declaration in another Bean Declaration as follows −
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
Now, rather than needing to specify both ConfigA.class and ConfigB.class when instantiating the context, only ConfigB needs to be supplied as follows −
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
การโทรกลับตลอดอายุการใช้งาน
คำอธิบายประกอบ @Bean สนับสนุนการระบุวิธีการเริ่มต้นและวิธีการเรียกกลับการทำลายโดยพลการเช่นเดียวกับแอตทริบิวต์ init-method และ destroy-method ของ Spring XML บนองค์ประกอบ bean
public class Foo {
public void init() {
// initialization logic
}
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup" )
public Foo foo() {
return new Foo();
}
}
การระบุขอบเขตของถั่ว
ขอบเขตเริ่มต้นคือ singleton แต่คุณสามารถแทนที่สิ่งนี้ได้ด้วยคำอธิบายประกอบ @Scope ดังนี้ -
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public Foo foo() {
return new Foo();
}
}
คุณได้เห็นในทุกบทแล้วว่าแกนกลางของฤดูใบไม้ผลิคือ ApplicationContextซึ่งจัดการวงจรชีวิตที่สมบูรณ์ของถั่ว ApplicationContext เผยแพร่เหตุการณ์บางประเภทเมื่อโหลดถั่ว ตัวอย่างเช่นContextStartedEventถูกเผยแพร่เมื่อบริบทเริ่มต้นและContextStoppedEventถูกเผยแพร่เมื่อบริบทหยุดทำงาน
การจัดการในเหตุการณ์ApplicationContextให้บริการผ่านApplicationEventชั้นเรียนและApplicationListenerอินเตอร์เฟซ ดังนั้นหาก bean ใช้ApplicationListenerทุกครั้งที่ApplicationEventเผยแพร่ไปยัง ApplicationContext bean นั้นจะได้รับการแจ้งเตือน
Spring จัดให้มีเหตุการณ์มาตรฐานดังต่อไปนี้ -
ซีเนียร์ | กิจกรรมและคำอธิบายในตัวของฤดูใบไม้ผลิ |
---|---|
1 | ContextRefreshedEvent เหตุการณ์นี้เผยแพร่เมื่อApplicationContextเริ่มต้นหรือรีเฟรช นอกจากนี้ยังสามารถเพิ่มขึ้นโดยใช้เมธอด refresh () บนอินเทอร์เฟซConfigurableApplicationContext |
2 | ContextStartedEvent เหตุการณ์นี้จะเผยแพร่เมื่อApplicationContextเริ่มต้นโดยใช้เมธอด start () บนอินเทอร์เฟซConfigurableApplicationContext คุณสามารถสำรวจฐานข้อมูลของคุณหรือคุณสามารถรีสตาร์ทแอปพลิเคชันที่หยุดทำงานหลังจากได้รับกิจกรรมนี้ |
3 | ContextStoppedEvent เหตุการณ์นี้เผยแพร่เมื่อApplicationContextหยุดโดยใช้เมธอด stop () บนอินเทอร์เฟซConfigurableApplicationContext คุณสามารถทำงานแม่บ้านที่จำเป็นได้หลังจากได้รับกิจกรรมนี้ |
4 | ContextClosedEvent เหตุการณ์นี้เผยแพร่เมื่อปิดApplicationContextโดยใช้เมธอด close () บนอินเทอร์เฟซConfigurableApplicationContext บริบทปิดถึงจุดจบของชีวิต ไม่สามารถรีเฟรชหรือรีสตาร์ทได้ |
5 | RequestHandledEvent นี่เป็นเหตุการณ์เฉพาะเว็บที่บอกถั่วทั้งหมดว่ามีการให้บริการคำขอ HTTP แล้ว |
การจัดการเหตุการณ์ของ Spring เป็นแบบเธรดเดียวดังนั้นหากมีการเผยแพร่เหตุการณ์จนกว่าและเว้นแต่ผู้รับทั้งหมดจะได้รับข้อความกระบวนการจะถูกบล็อกและโฟลว์จะไม่ดำเนินการต่อ ดังนั้นควรใช้ความระมัดระวังในการออกแบบแอปพลิเคชันของคุณหากต้องใช้การจัดการเหตุการณ์
การฟังเหตุการณ์ตามบริบท
ในการฟังเหตุการณ์บริบท bean ควรใช้อินเทอร์เฟซApplicationListenerซึ่งมีเพียงวิธีเดียวonApplicationEvent(). ดังนั้นให้เราเขียนตัวอย่างเพื่อดูว่าเหตุการณ์แพร่กระจายและวิธีที่คุณสามารถใส่โค้ดของคุณเพื่อทำงานที่จำเป็นตามเหตุการณ์บางอย่างได้อย่างไร
ให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อสร้างแอปพลิเคชัน Spring -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาส Java HelloWorld , CStartEventHandler , CStopEventHandlerและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
4 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
5 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ CStartEventHandler.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class CStartEventHandler
implements ApplicationListener<ContextStartedEvent>{
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("ContextStartedEvent Received");
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ CStopEventHandler.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler
implements ApplicationListener<ContextStoppedEvent>{
public void onApplicationEvent(ContextStoppedEvent event) {
System.out.println("ContextStoppedEvent Received");
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
// Let us raise a start event.
context.start();
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
// Let us raise a stop event.
context.stop();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
<bean id = "cStartEventHandler" class = "com.tutorialspoint.CStartEventHandler"/>
<bean id = "cStopEventHandler" class = "com.tutorialspoint.CStopEventHandler"/>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received
หากคุณต้องการคุณสามารถเผยแพร่เหตุการณ์ที่กำหนดเองของคุณเองและหลังจากนั้นคุณสามารถบันทึกเหตุการณ์เดียวกันเพื่อดำเนินการกับเหตุการณ์ที่กำหนดเองเหล่านั้นได้ หากคุณสนใจที่จะเขียนเหตุการณ์ที่คุณกำหนดเองคุณสามารถตรวจสอบเหตุการณ์ที่กำหนดเองในฤดูใบไม้ผลิ
มีหลายขั้นตอนที่ต้องดำเนินการเพื่อเขียนและเผยแพร่เหตุการณ์ที่คุณกำหนดเอง ทำตามคำแนะนำที่ให้ไว้ในบทนี้เพื่อเขียนเผยแพร่และจัดการ Custom Spring Events
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์srcโฟลเดอร์ในโครงการที่สร้างขึ้น คลาสทั้งหมดจะถูกสร้างขึ้นภายใต้แพ็คเกจนี้ |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | สร้างคลาสเหตุการณ์CustomEventโดยการขยายApplicationEvent. คลาสนี้ต้องกำหนดคอนสตรัคเตอร์เริ่มต้นซึ่งควรสืบทอดคอนสตรัคเตอร์จากคลาส ApplicationEvent |
4 | เมื่อระดับกิจกรรมของคุณจะถูกกำหนดคุณสามารถเผยแพร่ได้จากระดับใด ๆ ให้เราพูดEventClassPublisherซึ่งดำเนินApplicationEventPublisherAware คุณจะต้องประกาศคลาสนี้ในไฟล์คอนฟิกูเรชัน XML เป็น bean เพื่อให้คอนเทนเนอร์สามารถระบุ bean เป็นผู้เผยแพร่เหตุการณ์เนื่องจากใช้อินเทอร์เฟซ ApplicationEventPublisherAware |
5 | เหตุการณ์ที่เผยแพร่สามารถจัดการได้ในคลาสให้เราพูดEventClassHandlerซึ่งใช้อินเทอร์เฟซApplicationListenerและใช้เมธอดonApplicationEventสำหรับเหตุการณ์ที่กำหนดเอง |
6 | สร้างไฟล์คอนฟิกูเรชันBeans.xmlภายใต้ไฟล์srcโฟลเดอร์และคลาสMainAppซึ่งจะทำงานเป็นแอปพลิเคชัน Spring |
7 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ CustomEvent.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent{
public CustomEvent(Object source) {
super(source);
}
public String toString(){
return "My Custom Event";
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ CustomEventPublisher.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
public void setApplicationEventPublisher (ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void publish() {
CustomEvent ce = new CustomEvent(this);
publisher.publishEvent(ce);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ CustomEventHandler.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
public class CustomEventHandler implements ApplicationListener<CustomEvent> {
public void onApplicationEvent(CustomEvent event) {
System.out.println(event.toString());
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ MainApp.java ไฟล์
package com.tutorialspoint;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
CustomEventPublisher cvp =
(CustomEventPublisher) context.getBean("customEventPublisher");
cvp.publish();
cvp.publish();
}
}
ต่อไปนี้เป็นไฟล์กำหนดค่า Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "customEventHandler" class = "com.tutorialspoint.CustomEventHandler"/>
<bean id = "customEventPublisher" class = "com.tutorialspoint.CustomEventPublisher"/>
</beans>
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยดีกับแอปพลิเคชันของคุณแอปพลิเคชันของคุณจะพิมพ์ข้อความต่อไปนี้ -
y Custom Event
y Custom Event
องค์ประกอบสำคัญอย่างหนึ่งของ Spring Framework คือไฟล์ Aspect oriented programming (AOP)กรอบ. Aspect-Oriented Programming ทำให้เกิดการแยกลอจิกของโปรแกรมออกเป็นส่วนต่างๆที่เรียกว่าข้อกังวล เรียกว่าฟังก์ชันที่ครอบคลุมหลายจุดของแอปพลิเคชันcross-cutting concernsและความกังวลข้ามมิติเหล่านี้เป็นแนวคิดที่แยกออกจากตรรกะทางธุรกิจของแอปพลิเคชัน มีตัวอย่างด้านต่างๆที่ดีเช่นการบันทึกการตรวจสอบธุรกรรมที่เปิดเผยความปลอดภัยการแคชเป็นต้น
หน่วยหลักของโมดูลาร์ใน OOP คือคลาสในขณะที่ใน AOP หน่วยของโมดูลาร์คือด้าน Dependency Injection ช่วยให้คุณแยกวัตถุแอปพลิเคชันของคุณออกจากกันและ AOP ช่วยให้คุณแยกข้อกังวลข้ามการตัดออกจากวัตถุที่ส่งผลกระทบ AOP เป็นเหมือนทริกเกอร์ในภาษาโปรแกรมเช่น Perl, .NET, Java และอื่น ๆ
โมดูล Spring AOP ให้ตัวดักจับเพื่อสกัดกั้นแอปพลิเคชัน ตัวอย่างเช่นเมื่อเรียกใช้เมธอดคุณสามารถเพิ่มฟังก์ชันพิเศษก่อนหรือหลังการเรียกใช้เมธอดได้
คำศัพท์ AOP
ก่อนที่เราจะเริ่มทำงานกับ AOP ขอให้เราทำความคุ้นเคยกับแนวคิดและคำศัพท์ของ AOP ข้อกำหนดเหล่านี้ไม่เฉพาะเจาะจงสำหรับ Spring แต่เกี่ยวข้องกับ AOP
ซีเนียร์ No | เงื่อนไขและคำอธิบาย |
---|---|
1 | Aspect นี่คือโมดูลที่มีชุด API ที่ให้ข้อกำหนดการตัดขวาง ตัวอย่างเช่นโมดูลการบันทึกจะถูกเรียกว่าด้าน AOP สำหรับการบันทึก แอปพลิเคชันสามารถมีหลายแง่มุมขึ้นอยู่กับความต้องการ |
2 | Join point สิ่งนี้แสดงถึงจุดในแอปพลิเคชันของคุณที่คุณสามารถเสียบด้าน AOP ได้ คุณสามารถพูดได้ว่าเป็นสถานที่จริงในแอปพลิเคชันที่จะดำเนินการโดยใช้ Spring AOP framework |
3 | Advice นี่คือการดำเนินการจริงที่ต้องดำเนินการก่อนหรือหลังการเรียกใช้เมธอด นี่คือส่วนหนึ่งของโค้ดจริงที่เรียกใช้ระหว่างการดำเนินการโปรแกรมโดย Spring AOP framework |
4 | Pointcut นี่คือชุดของจุดเชื่อมต่ออย่างน้อยหนึ่งจุดที่ควรดำเนินการตามคำแนะนำ คุณสามารถระบุคำสั่งชี้โดยใช้นิพจน์หรือรูปแบบดังที่เราจะเห็นในตัวอย่าง AOP ของเรา |
5 | Introduction บทนำช่วยให้คุณสามารถเพิ่มวิธีการหรือแอตทริบิวต์ใหม่ให้กับคลาสที่มีอยู่ |
6 | Target object วัตถุที่ได้รับคำแนะนำจากด้านใดด้านหนึ่งหรือมากกว่านั้น วัตถุนี้จะเป็นวัตถุพร็อกซีเสมอหรือเรียกอีกอย่างว่าวัตถุที่แนะนำ |
7 | Weaving การทอผ้าเป็นกระบวนการเชื่อมโยงด้านต่างๆกับประเภทแอปพลิเคชันหรือวัตถุอื่น ๆ เพื่อสร้างวัตถุที่แนะนำ ซึ่งสามารถทำได้ในเวลาคอมไพล์เวลาโหลดหรือรันไทม์ |
ประเภทของคำแนะนำ
แง่มุมของสปริงสามารถใช้ได้กับคำแนะนำห้าประเภทดังต่อไปนี้ -
ซีเนียร์ No | คำแนะนำและคำอธิบาย |
---|---|
1 | before เรียกใช้คำแนะนำก่อนการดำเนินการตามวิธีการ |
2 | after เรียกใช้คำแนะนำหลังจากดำเนินการตามวิธีการโดยไม่คำนึงถึงผลลัพธ์ |
3 | after-returning เรียกใช้คำแนะนำหลังจากการดำเนินการเมธอดต่อเมื่อเมธอดดำเนินการสำเร็จ |
4 | after-throwing เรียกใช้คำแนะนำหลังจากการดำเนินการเมธอดต่อเมื่อเมธอดออกจากการยกเว้นเท่านั้น |
5 | around เรียกใช้คำแนะนำก่อนและหลังเรียกใช้วิธีการที่แนะนำ |
การใช้งานด้านที่กำหนดเอง
สปริงรองรับ @AspectJ annotation style แนวทางและ schema-basedแนวทางในการใช้แง่มุมที่กำหนดเอง สองแนวทางนี้ได้อธิบายโดยละเอียดแล้วในส่วนต่อไปนี้
ซีเนียร์ No | แนวทางและคำอธิบาย |
---|---|
1 | ตาม XML Schema แง่มุมถูกนำไปใช้โดยใช้คลาสปกติพร้อมกับคอนฟิกูเรชันตาม XML |
2 | @AspectJ อิง @AspectJ หมายถึงรูปแบบของการประกาศแง่มุมเป็นคลาส Java ปกติที่มีคำอธิบายประกอบ Java 5 |
ในขณะที่ทำงานกับฐานข้อมูลโดยใช้ JDBC แบบเก่าจะยุ่งยากในการเขียนโค้ดที่ไม่จำเป็นเพื่อจัดการกับข้อยกเว้นการเปิดและปิดการเชื่อมต่อฐานข้อมูลเป็นต้นอย่างไรก็ตาม Spring JDBC Framework จะดูแลรายละเอียดระดับต่ำทั้งหมดโดยเริ่มตั้งแต่การเปิดการเชื่อมต่อเตรียม และดำเนินการคำสั่ง SQL ข้อยกเว้นของกระบวนการจัดการธุรกรรมและปิดการเชื่อมต่อในที่สุด
ดังนั้นสิ่งที่คุณต้องทำก็แค่กำหนดพารามิเตอร์การเชื่อมต่อและระบุคำสั่ง SQL ที่จะดำเนินการและทำงานที่จำเป็นสำหรับการทำซ้ำแต่ละครั้งในขณะที่ดึงข้อมูลจากฐานข้อมูล
Spring JDBC มีหลายแนวทางและคลาสที่แตกต่างกันเพื่อเชื่อมต่อกับฐานข้อมูล ฉันจะใช้แนวทางคลาสสิกและเป็นที่นิยมมากที่สุดซึ่งใช้ประโยชน์จากJdbcTemplateคลาสของกรอบ นี่คือคลาสเฟรมเวิร์กกลางที่จัดการการสื่อสารฐานข้อมูลและการจัดการข้อยกเว้นทั้งหมด
คลาส JdbcTemplate
คลาส JDBC Template เรียกใช้เคียวรี SQL อัพเดตคำสั่งเก็บการเรียกโพรซีเดอร์ดำเนินการซ้ำบน ResultSets และแยกค่าพารามิเตอร์ที่ส่งคืน นอกจากนี้ยังตรวจจับข้อยกเว้น JDBC และแปลเป็นลำดับชั้นข้อยกเว้นทั่วไปที่ให้ข้อมูลมากขึ้นซึ่งกำหนดไว้ในแพ็คเกจ org.springframework.dao
อินสแตนซ์ของคลาสJdbcTemplateคือthreadsafeเมื่อกำหนดค่าแล้ว ดังนั้นคุณสามารถกำหนดค่าอินสแตนซ์เดียวของJdbcTemplateจากนั้นฉีดข้อมูลอ้างอิงที่แชร์นี้ลงใน DAO หลายตัวได้อย่างปลอดภัย
แนวทางปฏิบัติทั่วไปเมื่อใช้คลาส JDBC Template คือการกำหนดค่าDataSourceในไฟล์คอนฟิกูเรชัน Spring ของคุณจากนั้นใช้การพึ่งพา DataSource bean ที่แบ่งใช้ในคลาส DAO ของคุณและ JdbcTemplate จะถูกสร้างขึ้นในตัวตั้งค่าสำหรับ DataSource
การกำหนดค่าแหล่งข้อมูล
ให้เราสร้างตารางฐานข้อมูล Student ในฐานข้อมูลของเรา TEST. เราถือว่าคุณกำลังทำงานกับฐานข้อมูล MySQL หากคุณทำงานกับฐานข้อมูลอื่นคุณสามารถเปลี่ยนการสืบค้น DDL และ SQL ของคุณได้
CREATE TABLE Student(
ID INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY (ID)
);
ตอนนี้เราจำเป็นต้องจัดหาแหล่งข้อมูลให้กับเทมเพลต JDBC เพื่อให้สามารถกำหนดค่าตัวเองเพื่อเข้าถึงฐานข้อมูลได้ คุณสามารถกำหนดค่า DataSource ในไฟล์ XML ด้วยส่วนของโค้ดดังที่แสดงในข้อมูลโค้ดต่อไปนี้ -
<bean id = "dataSource"
class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
<property name = "username" value = "root"/>
<property name = "password" value = "password"/>
</bean>
วัตถุการเข้าถึงข้อมูล (DAO)
DAO ย่อมาจาก Data Access Object ซึ่งมักใช้สำหรับการโต้ตอบกับฐานข้อมูล DAO มีอยู่เพื่อจัดหาวิธีการอ่านและเขียนข้อมูลไปยังฐานข้อมูลและควรเปิดเผยฟังก์ชันนี้ผ่านอินเทอร์เฟซที่แอปพลิเคชันที่เหลือจะเข้าถึงได้
การสนับสนุน DAO ใน Spring ทำให้ง่ายต่อการทำงานกับเทคโนโลยีการเข้าถึงข้อมูลเช่น JDBC, Hibernate, JPA หรือ JDO ในลักษณะที่สอดคล้องกัน
การดำเนินการคำสั่ง SQL
ให้เราดูว่าเราสามารถดำเนินการ CRUD (สร้างอ่านอัปเดตและลบ) บนตารางฐานข้อมูลโดยใช้ SQL และ JDBC Template ได้อย่างไร
Querying for an integer
String SQL = "select count(*) from Student";
int rowCount = jdbcTemplateObject.queryForInt( SQL );
Querying for a long
String SQL = "select count(*) from Student";
long rowCount = jdbcTemplateObject.queryForLong( SQL );
A simple query using a bind variable
String SQL = "select age from Student where id = ?";
int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});
Querying for a String
String SQL = "select name from Student where id = ?";
String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);
Querying and returning an object
String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(
SQL, new Object[]{10}, new StudentMapper());
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
Querying and returning multiple objects
String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(
SQL, new StudentMapper());
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
Inserting a row into the table
String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );
Updating a row into the table
String SQL = "update Student set name = ? where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );
Deleting a row from the table
String SQL = "delete Student where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{20} );
การดำเนินการคำสั่ง DDL
คุณสามารถใช้ไฟล์ execute(..)วิธีการจากjdbcTemplateเพื่อดำเนินการคำสั่ง SQL หรือคำสั่ง DDL ต่อไปนี้เป็นตัวอย่างการใช้คำสั่ง CREATE เพื่อสร้างตาราง -
String SQL = "CREATE TABLE Student( " +
"ID INT NOT NULL AUTO_INCREMENT, " +
"NAME VARCHAR(20) NOT NULL, " +
"AGE INT NOT NULL, " +
"PRIMARY KEY (ID));"
jdbcTemplateObject.execute( SQL );
ตัวอย่าง Spring JDBC Framework
จากแนวคิดข้างต้นให้เราตรวจสอบตัวอย่างที่สำคัญบางส่วนซึ่งจะช่วยให้คุณเข้าใจการใช้งานกรอบงาน JDBC ในฤดูใบไม้ผลิ -
ซีเนียร์ | ตัวอย่างและคำอธิบาย |
---|---|
1 | ตัวอย่าง Spring JDBC ตัวอย่างนี้จะอธิบายวิธีการเขียนแอปพลิเคชัน Spring ที่ใช้ JDBC อย่างง่าย |
2 | SQL Stored Procedure ใน Spring เรียนรู้วิธีการเรียกใช้กระบวนงานที่จัดเก็บ SQL ในขณะที่ใช้ JDBC ใน Spring |
ธุรกรรมฐานข้อมูลคือลำดับของการดำเนินการที่ถือว่าเป็นหน่วยงานเดียว การดำเนินการเหล่านี้ควรเสร็จสิ้นทั้งหมดหรือไม่มีผลเลย การจัดการธุรกรรมเป็นส่วนสำคัญของแอปพลิเคชันระดับองค์กรที่มุ่งเน้น RDBMS เพื่อให้แน่ใจว่าข้อมูลมีความสมบูรณ์และสอดคล้องกัน แนวคิดของธุรกรรมสามารถอธิบายได้ด้วยคุณสมบัติหลักสี่ประการต่อไปนี้ที่อธิบายไว้ACID -
Atomicity - ธุรกรรมควรถือเป็นหน่วยการดำเนินการเดียวซึ่งหมายความว่าลำดับการดำเนินการทั้งหมดสำเร็จหรือไม่สำเร็จ
Consistency - แสดงถึงความสอดคล้องกันของความสมบูรณ์ของฐานข้อมูลคีย์หลักที่ไม่ซ้ำกันในตาราง ฯลฯ
Isolation- อาจมีการประมวลผลธุรกรรมหลายรายการด้วยชุดข้อมูลเดียวกันในเวลาเดียวกัน แต่ละธุรกรรมควรแยกออกจากผู้อื่นเพื่อป้องกันความเสียหายของข้อมูล
Durability - เมื่อธุรกรรมเสร็จสมบูรณ์ผลลัพธ์ของธุรกรรมนี้จะต้องถูกทำให้ถาวรและไม่สามารถลบออกจากฐานข้อมูลได้เนื่องจากระบบล้มเหลว
ระบบฐานข้อมูล RDBMS จริงจะรับประกันคุณสมบัติทั้งสี่ประการสำหรับแต่ละธุรกรรม มุมมองที่เรียบง่ายของธุรกรรมที่ออกให้กับฐานข้อมูลโดยใช้ SQL มีดังนี้ -
เริ่มต้นธุรกรรมโดยใช้คำสั่ง start transaction
ดำเนินการลบอัปเดตหรือแทรกต่างๆโดยใช้แบบสอบถาม SQL
หากการดำเนินการทั้งหมดประสบความสำเร็จให้ทำการกระทำมิฉะนั้นจะย้อนกลับการดำเนินการทั้งหมด
Spring framework จัดเตรียมเลเยอร์นามธรรมไว้ด้านบนของ API การจัดการธุรกรรมที่แตกต่างกัน การสนับสนุนการทำธุรกรรมของ Spring มีวัตถุประสงค์เพื่อเป็นทางเลือกให้กับธุรกรรม EJB โดยการเพิ่มความสามารถในการทำธุรกรรมให้กับ POJO Spring รองรับทั้งการจัดการธุรกรรมแบบเป็นโปรแกรมและแบบเปิดเผย EJB ต้องใช้แอ็พพลิเคชันเซิร์ฟเวอร์ แต่การจัดการธุรกรรม Spring สามารถดำเนินการได้โดยไม่ต้องใช้แอ็พพลิเคชันเซิร์ฟเวอร์
ธุรกรรมในพื้นที่กับทั่วโลก
ธุรกรรมภายในเฉพาะสำหรับทรัพยากรธุรกรรมเดียวเช่นการเชื่อมต่อ JDBC ในขณะที่ธุรกรรมส่วนกลางสามารถครอบคลุมทรัพยากรธุรกรรมหลายรายการเช่นธุรกรรมในระบบแบบกระจาย
การจัดการธุรกรรมภายในจะมีประโยชน์ในสภาพแวดล้อมการประมวลผลแบบรวมศูนย์ซึ่งส่วนประกอบของแอปพลิเคชันและทรัพยากรตั้งอยู่ที่ไซต์เดียวและการจัดการธุรกรรมเกี่ยวข้องกับตัวจัดการข้อมูลในเครื่องที่ทำงานบนเครื่องเดียวเท่านั้น การทำธุรกรรมในพื้นที่ทำได้ง่ายกว่า
จำเป็นต้องมีการจัดการธุรกรรมทั่วโลกในสภาพแวดล้อมการประมวลผลแบบกระจายซึ่งทรัพยากรทั้งหมดถูกกระจายไปยังระบบต่างๆ ในกรณีนี้การจัดการธุรกรรมจำเป็นต้องทำทั้งในระดับท้องถิ่นและระดับโลก ธุรกรรมแบบกระจายหรือทั่วโลกถูกดำเนินการในหลายระบบและการดำเนินการนั้นต้องการการประสานงานระหว่างระบบการจัดการธุรกรรมทั่วโลกและตัวจัดการข้อมูลภายในของระบบที่เกี่ยวข้องทั้งหมด
แบบเป็นโปรแกรมเทียบกับการประกาศ
Spring รองรับการจัดการธุรกรรมสองประเภท -
การจัดการธุรกรรมแบบเป็นโปรแกรม - ซึ่งหมายความว่าคุณต้องจัดการธุรกรรมด้วยความช่วยเหลือของการเขียนโปรแกรม ทำให้คุณมีความยืดหยุ่นสูง แต่ดูแลรักษายาก
การจัดการธุรกรรมที่เปิดเผย - หมายความว่าคุณแยกการจัดการธุรกรรมออกจากรหัสธุรกิจ คุณใช้เฉพาะคำอธิบายประกอบหรือการกำหนดค่าตาม XML เพื่อจัดการธุรกรรม
การจัดการธุรกรรมแบบเปิดเผยเป็นที่นิยมมากกว่าการจัดการธุรกรรมแบบเป็นโปรแกรมแม้ว่าจะมีความยืดหยุ่นน้อยกว่าการจัดการธุรกรรมแบบเป็นโปรแกรมซึ่งช่วยให้คุณสามารถควบคุมธุรกรรมผ่านรหัสของคุณได้ แต่ในฐานะที่เป็นความกังวลแบบ crosscutting การจัดการธุรกรรมแบบเปิดเผยสามารถแยกส่วนได้ด้วยวิธี AOP Spring สนับสนุนการจัดการธุรกรรมที่เปิดเผยผ่านกรอบ Spring AOP
Spring Transaction Abstractions
คีย์ของสิ่งที่เป็นนามธรรมของธุรกรรม Spring ถูกกำหนดโดยอินเตอร์เฟสorg.springframework.transaction.PlatformTransactionManagerซึ่งมีดังต่อไปนี้ -
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition);
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
ซีเนียร์ No | วิธีการและคำอธิบาย |
---|---|
1 | TransactionStatus getTransaction(TransactionDefinition definition) วิธีนี้ส่งคืนธุรกรรมที่ใช้งานอยู่ในปัจจุบันหรือสร้างรายการใหม่ตามลักษณะการแพร่กระจายที่ระบุ |
2 | void commit(TransactionStatus status) วิธีนี้จะทำธุรกรรมที่กำหนดโดยคำนึงถึงสถานะ |
3 | void rollback(TransactionStatus status) วิธีนี้ดำเนินการย้อนกลับของธุรกรรมที่กำหนด |
TransactionDefinitionคืออินเตอร์เฟซหลักของการสนับสนุนการทำธุรกรรมในฤดูใบไม้ผลิและมันถูกกำหนดไว้ดังต่อไปนี้ -
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
String getName();
int getTimeout();
boolean isReadOnly();
}
ซีเนียร์ No | วิธีการและคำอธิบาย |
---|---|
1 | int getPropagationBehavior() วิธีนี้ส่งกลับพฤติกรรมการแพร่กระจาย Spring นำเสนอตัวเลือกการเผยแพร่ธุรกรรมทั้งหมดที่คุ้นเคยจาก EJB CMT |
2 | int getIsolationLevel() วิธีนี้จะคืนค่าระดับที่ธุรกรรมนี้แยกออกจากการทำงานของธุรกรรมอื่น ๆ |
3 | String getName() วิธีนี้ส่งคืนชื่อของธุรกรรมนี้ |
4 | int getTimeout() วิธีนี้จะคืนค่าเวลาเป็นวินาทีที่ธุรกรรมต้องเสร็จสมบูรณ์ |
5 | boolean isReadOnly() วิธีนี้ส่งคืนว่าธุรกรรมเป็นแบบอ่านอย่างเดียวหรือไม่ |
ต่อไปนี้เป็นค่าที่เป็นไปได้สำหรับระดับการแยก -
ซีเนียร์ No | การแยกและคำอธิบาย |
---|---|
1 | TransactionDefinition.ISOLATION_DEFAULT นี่คือระดับการแยกเริ่มต้น |
2 | TransactionDefinition.ISOLATION_READ_COMMITTED แสดงว่ามีการป้องกันการอ่านสกปรก การอ่านที่ไม่สามารถทำซ้ำได้และการอ่านแบบหลอนสามารถเกิดขึ้นได้ |
3 | TransactionDefinition.ISOLATION_READ_UNCOMMITTED ระบุว่าการอ่านสกปรกการอ่านที่ไม่สามารถทำซ้ำได้และการอ่านแบบหลอนสามารถเกิดขึ้นได้ |
4 | TransactionDefinition.ISOLATION_REPEATABLE_READ ระบุว่าการอ่านสกปรกและการอ่านที่ไม่สามารถทำซ้ำได้ถูกป้องกัน การอ่านผีสามารถเกิดขึ้นได้ |
5 | TransactionDefinition.ISOLATION_SERIALIZABLE ระบุว่าการอ่านสกปรกการอ่านที่ไม่สามารถทำซ้ำได้และการอ่านแบบหลอนถูกป้องกัน |
ต่อไปนี้เป็นค่าที่เป็นไปได้สำหรับประเภทการเผยแพร่ -
ซีเนียร์ | การขยายพันธุ์และคำอธิบาย |
---|---|
1 | TransactionDefinition.PROPAGATION_MANDATORY รองรับธุรกรรมปัจจุบัน แสดงข้อยกเว้นหากไม่มีธุรกรรมปัจจุบัน |
2 | TransactionDefinition.PROPAGATION_NESTED ดำเนินการภายในธุรกรรมที่ซ้อนกันหากมีธุรกรรมปัจจุบันอยู่ |
3 | TransactionDefinition.PROPAGATION_NEVER ไม่รองรับธุรกรรมปัจจุบัน แสดงข้อยกเว้นหากมีธุรกรรมปัจจุบันอยู่ |
4 | TransactionDefinition.PROPAGATION_NOT_SUPPORTED ไม่รองรับธุรกรรมปัจจุบัน ค่อนข้างจะดำเนินการโดยไม่ทำธุรกรรมเสมอ |
5 | TransactionDefinition.PROPAGATION_REQUIRED รองรับธุรกรรมปัจจุบัน สร้างใหม่หากไม่มีอยู่ |
6 | TransactionDefinition.PROPAGATION_REQUIRES_NEW สร้างธุรกรรมใหม่ระงับธุรกรรมปัจจุบันหากมีอยู่ |
7 | TransactionDefinition.PROPAGATION_SUPPORTS รองรับธุรกรรมปัจจุบัน ดำเนินการโดยไม่ทำธุรกรรมหากไม่มีอยู่ |
8 | TransactionDefinition.TIMEOUT_DEFAULT ใช้การหมดเวลาเริ่มต้นของระบบธุรกรรมที่อยู่เบื้องหลังหรือไม่มีเลยหากไม่สนับสนุนการหมดเวลา |
TransactionStatusอินเตอร์เฟซให้เป็นวิธีที่ง่ายสำหรับรหัสการทำธุรกรรมที่จะดำเนินการทำธุรกรรมการควบคุมและสถานะการทำธุรกรรมแบบสอบถาม
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | boolean hasSavepoint() วิธีนี้จะส่งคืนว่าธุรกรรมนี้มีจุดบันทึกภายในหรือไม่กล่าวคือถูกสร้างขึ้นเป็นธุรกรรมซ้อนกันโดยยึดตามจุดบันทึก |
2 | boolean isCompleted() วิธีนี้จะส่งคืนว่าธุรกรรมนี้เสร็จสมบูรณ์หรือไม่กล่าวคือไม่ว่าจะได้รับการยืนยันแล้วหรือย้อนกลับ |
3 | boolean isNewTransaction() วิธีนี้จะคืนค่าจริงในกรณีที่ธุรกรรมปัจจุบันเป็นธุรกรรมใหม่ |
4 | boolean isRollbackOnly() วิธีนี้จะคืนค่าว่าธุรกรรมถูกทำเครื่องหมายว่าเป็นแบบย้อนกลับเท่านั้น |
5 | void setRollbackOnly() วิธีนี้ตั้งค่าธุรกรรมเป็นการย้อนกลับเท่านั้น |
เฟรมเวิร์ก Spring Web MVC มีสถาปัตยกรรม Model-View-Controller (MVC) และส่วนประกอบที่พร้อมใช้งานเพื่อพัฒนาเว็บแอปพลิเคชันที่ยืดหยุ่นและทำงานร่วมกันอย่างหลวม ๆ รูปแบบ MVC ส่งผลให้เกิดการแยกแง่มุมต่างๆของแอปพลิเคชัน (ตรรกะอินพุตตรรกะทางธุรกิจและตรรกะ UI) ในขณะที่ให้การเชื่อมต่อแบบหลวม ๆ ระหว่างองค์ประกอบเหล่านี้
Model ห่อหุ้มข้อมูลแอปพลิเคชันและโดยทั่วไปจะประกอบด้วย POJO
View รับผิดชอบในการแสดงผลข้อมูลแบบจำลองและโดยทั่วไปจะสร้างเอาต์พุต HTML ที่เบราว์เซอร์ของไคลเอ็นต์สามารถตีความได้
Controller มีหน้าที่ในการประมวลผลคำขอของผู้ใช้และสร้างแบบจำลองที่เหมาะสมและส่งต่อไปยังมุมมองสำหรับการแสดงผล
DispatcherServlet
เฟรมเวิร์ก Spring Web model-view-controller (MVC) ได้รับการออกแบบโดยใช้DispatcherServletที่จัดการคำขอและการตอบกลับ HTTP ทั้งหมด ขั้นตอนการประมวลผลคำร้องขอของ Spring Web MVC DispatcherServletแสดงในแผนภาพต่อไปนี้ -
ต่อไปนี้เป็นลำดับของเหตุการณ์ที่สอดคล้องกับคำขอ HTTP ขาเข้าไปยังDispatcherServlet -
หลังจากได้รับการร้องขอ HTTP, DispatcherServletคำปรึกษาHandlerMappingจะเรียกที่เหมาะสมควบคุม
ควบคุมจะใช้เวลาการร้องขอและเรียกวิธีการบริการที่เหมาะสมขึ้นอยู่กับการรับใช้หรือวิธีการ POST วิธีการบริการจะกำหนดรูปแบบข้อมูลที่อยู่บนพื้นฐานของตรรกะทางธุรกิจที่กำหนดและผลตอบแทนที่ดูชื่อไปDispatcherServlet
DispatcherServletจะใช้ความช่วยเหลือจากViewResolverรถกระบะมุมมองที่กำหนดไว้สำหรับการร้องขอ
เมื่อการดูเสร็จสิ้นDispatcherServletจะส่งผ่านข้อมูลโมเดลไปยังมุมมองซึ่งแสดงผลบนเบราว์เซอร์ในที่สุด
ส่วนประกอบที่กล่าวถึงข้างต้นทั้งหมดเช่น HandlerMapping, Controller และ ViewResolver เป็นส่วนหนึ่งของWebApplicationContextซึ่งเป็นส่วนเสริมของApplicationContextธรรมดาที่มีคุณสมบัติพิเศษบางอย่างที่จำเป็นสำหรับเว็บแอปพลิเคชัน
การกำหนดค่าที่จำเป็น
คุณต้องแมปคำขอที่คุณต้องการให้DispatcherServletจัดการโดยใช้การแมป URL ในไฟล์web.xmlไฟล์. ต่อไปนี้เป็นตัวอย่างเพื่อแสดงการประกาศและการแมปสำหรับHelloWeb ตัวอย่างDispatcherServlet -
<web-app id = "WebApp_ID" version = "2.4"
xmlns = "http://java.sun.com/xml/ns/j2ee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>
web.xmlไฟล์จะถูกเก็บไว้ในไดเรกทอรี WebContent / WEB-INF ของเว็บแอปพลิเคชันของคุณ เมื่อเริ่มต้นของHelloWeb DispatcherServlet เฟรมเวิร์กจะพยายามโหลดบริบทของแอปพลิเคชันจากไฟล์ชื่อ [servlet-name]-servlet.xmlอยู่ใน WebContent / WEB-INFdirectory ของแอปพลิเคชัน ในกรณีนี้ไฟล์ของเราจะเป็นHelloWebservlet.xml.
ถัดไปแท็ก <servlet-mapping> ระบุว่า URL ใดที่จะจัดการโดย DispatcherServlet ที่นี่คำขอ HTTP ทั้งหมดที่ลงท้ายด้วย.jsp จะถูกจัดการโดยไฟล์ HelloWeb DispatcherServlet
ถ้าคุณไม่ต้องการใช้ชื่อไฟล์ดีฟอลต์เป็น[servlet-name] -servlet.xmlและตำแหน่งดีฟอลต์เป็นWebContent / WEB-INFคุณสามารถกำหนดชื่อไฟล์และตำแหน่งนี้เองได้โดยการเพิ่มตัวฟัง servlet ContextLoaderListenerในไฟล์ web.xml ของคุณ ดังต่อไปนี้ -
<web-app...>
<!-------- DispatcherServlet definition goes here----->
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
ตอนนี้ให้เราตรวจสอบการกำหนดค่าที่จำเป็นสำหรับ HelloWeb-servlet.xmlวางไว้ในไดเรกทอรี WebContent / WEB-INFของเว็บแอปพลิเคชันของคุณ-
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:context = "http://www.springframework.org/schema/context"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package = "com.tutorialspoint" />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/jsp/" />
<property name = "suffix" value = ".jsp" />
</bean>
</beans>
ต่อไปนี้เป็นประเด็นสำคัญเกี่ยวกับ HelloWeb-servlet.xml ไฟล์ -
ไฟล์[servlet-name] -servlet.xmlจะถูกใช้เพื่อสร้าง bean ที่กำหนดโดยจะแทนที่นิยามของ bean ใด ๆ ที่กำหนดด้วยชื่อเดียวกันในขอบเขตส่วนกลาง
<บริบท: องค์ประกอบสแกน ... >แท็กจะใช้เพื่อเปิดใช้งานความสามารถในการสแกนคำอธิบายประกอบฤดูใบไม้ผลิ MVC ซึ่งจะช่วยให้เพื่อให้การใช้คำอธิบายประกอบเช่น @Controller และ @RequestMapping ฯลฯ
InternalResourceViewResolverจะมีกฎระเบียบที่กำหนดไว้ในการแก้ไขชื่อมุมมอง ตามกฎที่กำหนดไว้ข้างต้นมุมมองเชิงตรรกะที่มีชื่อว่าhelloจะมอบหมายให้การดำเนินงานมุมมองที่ตั้งอยู่ที่/WEB-INF/jsp/hello.jsp
ส่วนต่อไปนี้จะแสดงวิธีการสร้างส่วนประกอบจริงของคุณเช่นคอนโทรลเลอร์โมเดลและมุมมอง
การกำหนดคอนโทรลเลอร์
DispatcherServlet มอบหมายการร้องขอไปยังคอนโทรลเลอร์เพื่อดำเนินการฟังก์ชันเฉพาะสำหรับมัน @Controllerคำอธิบายประกอบบ่งชี้ว่าคลาสหนึ่ง ๆ ทำหน้าที่เป็นตัวควบคุม @RequestMapping คำอธิบายประกอบใช้เพื่อแมป URL กับทั้งคลาสหรือวิธีการจัดการเฉพาะ
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
@Controllerคำอธิบายประกอบกำหนดคลาสเป็นตัวควบคุม Spring MVC นี่คือการใช้งานครั้งแรกของ@RequestMapping บ่งชี้ว่าวิธีการจัดการทั้งหมดบนคอนโทรลเลอร์นี้สัมพันธ์กับ /helloเส้นทาง. คำอธิบายประกอบถัดไป@RequestMapping(method = RequestMethod.GET)ใช้เพื่อประกาศเมธอด theprintHello () เป็นวิธีการบริการเริ่มต้นของคอนโทรลเลอร์เพื่อจัดการคำขอ HTTP GET คุณสามารถกำหนดวิธีการอื่นเพื่อจัดการกับคำขอ POST ที่ URL เดียวกันได้
คุณสามารถเขียนตัวควบคุมข้างต้นในรูปแบบอื่นซึ่งคุณสามารถเพิ่มแอตทริบิวต์เพิ่มเติมใน@RequestMapping ได้ดังนี้ -
@Controller
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
value แอตทริบิวต์ระบุ URL ที่จะแม็พเมธอดตัวจัดการและ methodแอตทริบิวต์กำหนดวิธีการบริการเพื่อจัดการคำขอ HTTP GET ประเด็นสำคัญต่อไปนี้ควรสังเกตเกี่ยวกับคอนโทรลเลอร์ที่กำหนดไว้ข้างต้น -
คุณจะกำหนดตรรกะทางธุรกิจที่จำเป็นภายในวิธีการบริการ คุณสามารถเรียกใช้วิธีอื่นในวิธีนี้ได้ตามข้อกำหนด
ตามตรรกะทางธุรกิจที่กำหนดไว้คุณจะสร้างแบบจำลองภายในวิธีนี้ คุณสามารถใช้ setter แอตทริบิวต์โมเดลที่แตกต่างกันและแอตทริบิวต์เหล่านี้จะเข้าถึงได้โดยมุมมองเพื่อนำเสนอผลลัพธ์สุดท้าย ตัวอย่างนี้สร้างโมเดลที่มีแอตทริบิวต์ "message"
วิธีการบริการที่กำหนดสามารถส่งคืนสตริงซึ่งมีชื่อของ viewเพื่อใช้ในการแสดงผลแบบจำลอง ตัวอย่างนี้ส่งคืน "hello" เป็นชื่อมุมมองเชิงตรรกะ
การสร้างมุมมอง JSP
Spring MVC รองรับมุมมองหลายประเภทสำหรับเทคโนโลยีการนำเสนอที่แตกต่างกัน ซึ่งรวมถึง - JSPs, HTML, PDF, แผ่นงาน Excel, XML, เทมเพลต Velocity, XSLT, JSON, Atom และฟีด RSS, JasperReports เป็นต้น แต่โดยทั่วไปเราใช้เทมเพลต JSP ที่เขียนด้วย JSTL
ให้เราเขียนง่ายๆ hello ดูใน /WEB-INF/hello/hello.jsp -
<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
ที่นี่ ${message}เป็นแอตทริบิวต์ที่เราได้ตั้งค่าไว้ใน Controller คุณสามารถมีแอตทริบิวต์หลายรายการที่จะแสดงในมุมมองของคุณ
ตัวอย่างกรอบงาน Spring Web MVC
ตามแนวคิดข้างต้นให้เราตรวจสอบตัวอย่างที่สำคัญบางส่วนซึ่งจะช่วยคุณในการสร้าง Spring Web Applications ของคุณ -
ซีเนียร์ | ตัวอย่างและคำอธิบาย |
---|---|
1 | ตัวอย่าง Spring MVC Hello World ตัวอย่างนี้จะอธิบายวิธีการเขียนแอปพลิเคชัน Spring Web Hello World อย่างง่าย |
2 | ตัวอย่างการจัดการแบบฟอร์ม Spring MVC ตัวอย่างนี้จะอธิบายวิธีการเขียนแอปพลิเคชัน Spring Web โดยใช้แบบฟอร์ม HTML เพื่อส่งข้อมูลไปยังคอนโทรลเลอร์และแสดงผลลัพธ์ที่ประมวลผล |
3 | ตัวอย่างการเปลี่ยนเส้นทาง Spring Page เรียนรู้วิธีใช้ฟังก์ชันการเปลี่ยนเส้นทางเพจใน Spring MVC Framework |
4 | ตัวอย่าง Spring Static Pages เรียนรู้วิธีเข้าถึงเพจแบบคงที่พร้อมกับเพจแบบไดนามิกใน Spring MVC Framework |
5 | ตัวอย่างการจัดการข้อยกเว้นสปริง เรียนรู้วิธีจัดการข้อยกเว้นใน Spring MVC Framework |
นี่คือฟังก์ชัน Log4J ที่ใช้งานง่ายมากในแอปพลิเคชัน Spring ตัวอย่างต่อไปนี้จะนำคุณผ่านขั้นตอนง่ายๆในการอธิบายการรวมอย่างง่ายระหว่าง Log4J และ Spring
เราถือว่าคุณมีอยู่แล้ว log4Jติดตั้งบนเครื่องของคุณ หากคุณยังไม่มีคุณสามารถดาวน์โหลดได้จากhttps://logging.apache.org/และแตกไฟล์ซิปในโฟลเดอร์ใดก็ได้ เราจะใช้เฉพาะlog4j-x.y.z.jar ในโครงการของเรา
ต่อไปให้เรามี Eclipse IDE ที่ใช้งานได้และทำตามขั้นตอนต่อไปนี้เพื่อพัฒนาเว็บแอปพลิเคชันแบบไดนามิกฟอร์มโดยใช้ Spring Web Framework -
ขั้นตอน | คำอธิบาย |
---|---|
1 | สร้างโปรเจ็กต์ด้วยชื่อSpringExampleและสร้างแพ็คเกจcom.tutorialspointภายใต้ไฟล์src โฟลเดอร์ในโครงการที่สร้างขึ้น |
2 | เพิ่มไลบรารี Spring ที่จำเป็นโดยใช้ตัวเลือกเพิ่ม JAR ภายนอกตามที่อธิบายไว้ในบทตัวอย่าง Spring Hello World |
3 | เพิ่ม log4j ห้องสมุดlog4j-xyzjarเช่นกันในโครงการของคุณโดยใช้ใช้เพิ่มภายนอกไห |
4 | สร้างคลาส Java HelloWorldและMainAppภายใต้แพ็คเกจcom.tutorialspoint |
5 | สร้างไฟล์คอนฟิกูเรชัน Beans Beans.xmlภายใต้ไฟล์src โฟลเดอร์ |
6 | สร้างไฟล์คอนฟิกูเรชันlog4J log4j.propertiesภายใต้ไฟล์src โฟลเดอร์ |
7 | ขั้นตอนสุดท้ายคือการสร้างเนื้อหาของไฟล์ Java และไฟล์ Bean Configuration และเรียกใช้แอปพลิเคชันตามที่อธิบายด้านล่าง |
นี่คือเนื้อหาของ HelloWorld.java ไฟล์
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage() {
System.out.println("Your Message : " + message);
}
}
ต่อไปนี้เป็นเนื้อหาของไฟล์ที่สอง MainApp.java
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.log4j.Logger;
public class MainApp {
static Logger log = Logger.getLogger(MainApp.class.getName());
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
log.info("Going to create HelloWord Obj");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
log.info("Exiting the program");
}
}
คุณสามารถสร้าง debug และ errorข้อความในลักษณะเดียวกันกับที่เราสร้างข้อความข้อมูล ตอนนี้ให้เราดูเนื้อหาของBeans.xml ไฟล์
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
ต่อไปนี้เป็นเนื้อหาของ log4j.properties ซึ่งกำหนดกฎมาตรฐานที่จำเป็นสำหรับ Log4J ในการสร้างข้อความบันทึก
# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
# Set the name of the file
log4j.appender.FILE.File=C:\\log.out
# Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
# Set the append to false, overwrite
log4j.appender.FILE.Append=false
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
เมื่อคุณสร้างไฟล์การกำหนดค่าซอร์สและบีนเสร็จแล้วให้เราเรียกใช้แอปพลิเคชัน หากทุกอย่างเรียบร้อยกับแอปพลิเคชันของคุณสิ่งนี้จะพิมพ์ข้อความต่อไปนี้ในคอนโซล Eclipse -
Your Message : Hello World!
หากคุณตรวจสอบไดรฟ์ C: \\ ของคุณคุณจะพบไฟล์บันทึกของคุณ log.out ด้วยข้อความบันทึกต่างๆเช่นบางสิ่งดังต่อไปนี้ -
<!-- initialization log messages -->
Going to create HelloWord Obj
Returning cached instance of singleton bean 'helloWorld'
Exiting the program
Jakarta Commons Logging (JCL) API
หรือคุณสามารถใช้ Jakarta Commons Logging (JCL)API เพื่อสร้างบันทึกในแอปพลิเคชัน Spring ของคุณ สามารถดาวน์โหลด JCL ได้จากไฟล์https://jakarta.apache.org/commons/logging/. ไฟล์เดียวที่เราต้องการในทางเทคนิคจากแพ็คเกจนี้คือไฟล์commons-logging-xyzjarซึ่งต้องวางไว้ใน classpath ของคุณในลักษณะเดียวกับที่คุณใส่log4j-xyzjarในตัวอย่างข้างต้น
ในการใช้ฟังก์ชันการบันทึกคุณต้องมีอ็อบเจ็กต์org.apache.commons.logging.Logจากนั้นคุณสามารถเรียกใช้วิธีใดวิธีหนึ่งต่อไปนี้ตามข้อกำหนดของคุณ -
- ร้ายแรง (ข้อความวัตถุ)
- ข้อผิดพลาด (ข้อความวัตถุ)
- เตือน (ข้อความวัตถุ)
- ข้อมูล (ข้อความวัตถุ)
- debug (ข้อความวัตถุ)
- ติดตาม (ข้อความวัตถุ)
ต่อไปนี้คือการแทนที่ MainApp.java ซึ่งใช้ JCL API
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging. Log;
import org.apache.commons.logging. LogFactory;
public class MainApp {
static Log log = LogFactory.getLog(MainApp.class.getName());
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
log.info("Going to create HelloWord Obj");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
log.info("Exiting the program");
}
}
คุณต้องแน่ใจว่าคุณได้รวมไฟล์ commons-logging-xyzjar ไว้ในโปรเจ็กต์ของคุณก่อนที่จะคอมไพล์และรันโปรแกรม
ตอนนี้ทำให้ส่วนกำหนดค่าและเนื้อหาที่เหลือไม่เปลี่ยนแปลงในตัวอย่างข้างต้นหากคุณรวบรวมและเรียกใช้แอปพลิเคชันของคุณคุณจะได้รับผลลัพธ์ที่คล้ายกันกับสิ่งที่คุณได้รับจาก Log4J API