Framework Spring ถูกสร้างขึ้นเนื่องจากความซับซ้อนของการพัฒนาซอฟต์แวร์ ฤดูใบไม้ผลิใช้ Javabeans ขั้นพื้นฐานเพื่อทำสิ่งที่เป็นไปได้ก่อนหน้านี้โดย EJB อย่างไรก็ตามวัตถุประสงค์ของสปริงไม่ได้ จำกัด อยู่ที่การพัฒนาฝั่งเซิร์ฟเวอร์ จากมุมมองของความเรียบง่ายความสามารถในการทดสอบและการมีเพศสัมพันธ์แบบหลวมแอปพลิเคชัน Java ส่วนใหญ่จะได้รับประโยชน์จากฤดูใบไม้ผลิ ฤดูใบไม้ผลิเป็นแบบควบคุมการผกผัน (IOC) ที่มีน้ำหนักเบาและกรอบคอนเทนเนอร์ที่มุ่งเน้น (AOP)
◆วัตถุประสงค์: แก้ปัญหาความซับซ้อนของการพัฒนาแอปพลิเคชันองค์กร
◆ฟังก์ชั่น: ใช้ Javabean พื้นฐานแทน EJB และให้ฟังก์ชั่นแอปพลิเคชันระดับองค์กรมากขึ้น
◆ขอบเขต: แอปพลิเคชัน Java ใด ๆ
การผกผันของการควบคุม (IOC เป็นตัวย่อภาษาอังกฤษ) ให้สิทธิ์ในการสร้างวัตถุให้กับเฟรมเวิร์กซึ่งเป็นคุณลักษณะที่สำคัญของเฟรมเวิร์กและไม่ใช่คำพิเศษสำหรับการเขียนโปรแกรมเชิงวัตถุ มันรวมถึงการฉีดพึ่งพาและการค้นหาการพึ่งพา ในเลเยอร์ธุรกิจแบบดั้งเดิมเมื่อต้องการทรัพยากรทรัพยากรใหม่จะพบได้ในเลเยอร์ธุรกิจเพื่อให้การมีเพศสัมพันธ์ (การพึ่งพาซึ่งกันและกันและความสัมพันธ์ระหว่างโปรแกรม) สูงขึ้น ตอนนี้มอบส่วนใหม่ให้กับฤดูใบไม้ผลิเพื่อให้ได้การทำงานร่วมกันสูงและการมีเพศสัมพันธ์ต่ำ กล่าวโดยย่อ: เดิมทีเมื่อใดก็ตามที่มีการเรียกวิธีการ DAO Layer หรือ Service Layer App จะใช้ใหม่และตอนนี้สิทธิ์ใหม่ถูกส่งไปยังฤดูใบไม้ผลิและทรัพยากรที่จำเป็นต้องได้รับจากฤดูใบไม้ผลิ!
1. ดาวน์โหลดแพ็คเกจ jar ที่พึ่งพาได้สำหรับเฟรมเวิร์ก
เว็บไซต์ฤดูใบไม้ผลิอย่างเป็นทางการคือ: http://spring.io/
ดาวน์โหลดแพ็คเกจ JAR: http://repo.springsource.org/libs-release-local/org/springframework/spring
2. นำเข้าแพ็คเกจ JAR พื้นฐาน
ในความเป็นจริงขวดหลักพื้นฐานรวมถึงถั่วบริบท; Core; แพ็คเกจนิพจน์และอื่น ๆ ขึ้นอยู่กับบันทึก log4j แน่นอนว่าเหยือกฤดูใบไม้ผลินั้นมากกว่านั้นพวกมันจะถูกเพิ่มเข้ามาอย่างช้าๆในระยะต่อมา
3. กำหนดค่าไฟล์การกำหนดค่า log4j
ไฟล์บันทึกถูกกำหนดในไดเรกทอรี SRC
### ข้อความบันทึกโดยตรงไปยัง stdout ### log4j.appender.stdout = org.apache.log4j.consoleAppenderlog4j.appender.stdout.target = System.errlog4j.appender.stdout.layout = org.apache.log4j.patternlayoutlog4j.aptdout %c {1}: %l - %m %n ### ข้อความโดยตรงไปยังไฟล์ mylog.log ### log4j.appender.file = org.apache.log4j.FileAppenderLog4j.appender.file.file = c/: mylog.loglog4j.appender.file.layout = org.aPache.log4j.patternlayoutlog4j.aphent.lay.lay %c {1}: %l - %m %n ### ตั้งค่าระดับบันทึก - สำหรับการบันทึกการบันทึก verbose เพิ่มเติม 'ข้อมูล' เป็น 'debug' ### log4j.rootlogger = ข้อมูล stdout4. ทดสอบว่าไฟล์บันทึกถูกปรับใช้สำเร็จหรือไม่
แพ็คเกจ com.clj.demo1; นำเข้า org.apache.log4j.logger; นำเข้า org.junit.test;/** * การใช้งานบันทึกการใช้งาน DEMO * @author Administrator * */คลาสสาธารณะ demo1 {// สร้างคลาสบันทึกส่วนตัวบันทึก logger = logger.getLogger @Test โมฆะสาธารณะ run1 () {// เปลี่ยนข้อมูลในแอตทริบิวต์ log4j.rootlogger เป็นปิดและ log.info ("ดำเนินการ"); -5. กำหนดอินเทอร์เฟซและใช้คลาส
อินเทอร์เฟซ:
แพ็คเกจ com.clj.demo2; อินเตอร์เฟสสาธารณะผู้ใช้บริการ {โมฆะสาธารณะ Sayshello ();}คลาสการดำเนินการ
แพ็คเกจ com.clj.demo2; ผู้ใช้ระดับสาธารณะ userserviceimpl ใช้ userservice {ชื่อสตริงส่วนตัว; สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } โมฆะสาธารณะ init () {system.out.println ("เริ่มต้น .. "); } โมฆะสาธารณะ sayshello () {system.out.println ("สวัสดีสปริง"+"/t"+ชื่อ); } โมฆะสาธารณะ destory () {system.out.println ("ทำลาย .. "); -6. กำหนดไฟล์การกำหนดค่าเฉพาะสปริง
กำหนดชื่อของ ApplicationContext.xml ตำแหน่งคือ SRC ซึ่งเป็นไดเรกทอรีเดียวกับไฟล์บันทึกนำเข้าข้อ จำกัด ที่เกี่ยวข้องและฉีดคลาสการใช้งานลงในไฟล์การกำหนดค่า เพียงแค่เริ่มต้นด้วยการเริ่มต้นใช้ข้อ จำกัด ถั่ว
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: p = "http://www.springframework.org/schema/p" xsi: schemalocation = "http://www.springframework.org/schema/beans ใช้แท็กถั่ว 1. ค่า ID นั้นไม่ซ้ำกัน (ต้องเขียน) 2. หมายเหตุ: คลาสคือการใช้งาน ClassPath ไม่ใช่อินเทอร์เฟซ (ต้องเขียน) 3. การเริ่มต้นทำงานก่อนที่วิธีการหลักจะถูกดำเนินการ (เลือกเขียน) 4. การเริ่มต้นทำงานหลังจากวิธีการหลักถูกดำเนินการ </ebean> </ebeans>
7. ทดสอบ
ระดับสาธารณะ DEMO1 { /*** วิธีดั้งเดิม* /@Test โมฆะสาธารณะเรียกใช้ () {// สร้างคลาสการใช้งาน UserserViceImpl S = ใหม่ UserserViceImpl (); S.SetName ("Jaxiansen"); S.Sayhello (); } / *** เวอร์ชันโรงงานเก่า beanfactory* โรงงานเก่าจะไม่สร้างวัตถุไฟล์กำหนดค่า* / @Test โมฆะสาธารณะ run2 () {beanfactory Factory = ใหม่ XMLBeanFactory (ใหม่ classPathResource ("ApplicationContext.xml")); Userservice US = (Userservice) Factory.GetBean ("Userservice"); US.Sayhello (); } /*** ใช้เมธอดสปริงเฟรมเวิร์ก IOC* สร้างเซิร์ฟเวอร์เริ่มต้นในเวอร์ชันใหม่ของโรงงานเพื่อสร้างวัตถุไฟล์การกำหนดค่าและไม่จำเป็นต้องโหลดโรงงานเมื่อโทรอีกครั้ง* /@Test โมฆะสาธารณะ run3 () {// สร้างโรงงานและโหลดไฟล์กำหนดค่าหลัก classpathxmlapplicationContext ("applicationcontext.xml"); // รับวัตถุจากโรงงาน (ค่า id ในไฟล์การกำหนดค่า polymorphism ถูกใช้ที่นี่) ผู้ใช้ userervice usi = (userservice) ac.getBean ("userservice"); // เรียกวิธีการของวัตถุเพื่อดำเนินการ usi.sayhello (); } /*** วิธีการสาธิตการทำลาย-วิธีการ* วิธีการทำลายถั่วจะไม่ถูกดำเนินการโดยอัตโนมัติ* เว้นแต่ว่าจะถูกเรียกโดยอัตโนมัติในขอบเขต = ซิงเกิลตันหรือในเว็บคอนเทนเนอร์ฟังก์ชันหลักหรือกรณีทดสอบจะต้องเรียกด้วยตนเอง ภายใต้ SRC) classPathxMlApplicationContext AC = ใหม่ classPathxMlApplicationContext ("ApplicationContext.xml"); // รับวัตถุจากโรงงาน (ค่า id ในไฟล์การกำหนดค่า polymorphism ถูกใช้ที่นี่) ผู้ใช้ userervice usi = (userservice) ac.getBean ("userservice"); // เรียกวิธีการของวัตถุเพื่อดำเนินการ usi.sayhello (); // คลาสการใช้งาน ApplicationContext ให้วิธีการใกล้ชิดและสามารถปิดโรงงานได้และวิธีการ destory-method สามารถดำเนินการได้ -ความแตกต่างระหว่างโรงงานเก่าและโรงงานใหม่
* ความแตกต่างระหว่าง BeanFactory และ ApplicationContext
* beanfactory - Beanfactory ใช้เวลาโหลดขี้เกียจและถั่วจะเริ่มต้นเฉพาะเมื่อคุณได้รับเป็นครั้งแรก
* ApplicationContext - เมื่อโหลด ApplicationContext.xml อินสแตนซ์เฉพาะของวัตถุถั่วจะถูกสร้างขึ้นและมีฟังก์ชั่นอื่น ๆ
* การจัดส่งเหตุการณ์
* การประกอบถั่วอัตโนมัติ
* การใช้บริบทของเลเยอร์แอปพลิเคชันต่างๆ
สรุป: นี่คือตัวอย่างพื้นฐานที่สุดซึ่งกำหนดค่าคลาสการใช้งานลงในไฟล์การกำหนดค่าสปริง ทุกครั้งที่เซิร์ฟเวอร์เริ่มต้นไฟล์การกำหนดค่าจะถูกโหลดดังนั้นจึงสร้างอินสแตนซ์คลาสการใช้งาน
1. การฉีดขึ้นอยู่กับการพึ่งพาคืออะไร?
ฤดูใบไม้ผลิสามารถจัดระเบียบวัตถุในระดับแอปพลิเคชัน J2EE ได้อย่างมีประสิทธิภาพ ไม่ว่าจะเป็นวัตถุแอ็คชั่นของเลเยอร์ควบคุมวัตถุบริการของเลเยอร์ธุรกิจหรือวัตถุ DAO ของเลเยอร์การคงอยู่มันสามารถประสานงานได้แบบออร์แกนิกและดำเนินการภายใต้การจัดการของฤดูใบไม้ผลิ ฤดูใบไม้ผลิจัดวัตถุของแต่ละชั้นเข้าด้วยกันในลักษณะคู่กันอย่างหลวม วัตถุการดำเนินการไม่จำเป็นต้องใส่ใจเกี่ยวกับการใช้งานวัตถุบริการเฉพาะวัตถุบริการไม่จำเป็นต้องใส่ใจเกี่ยวกับการใช้งานวัตถุเลเยอร์แบบถาวรและการเรียกไปยังวัตถุเลเยอร์แต่ละรายการนั้นมุ่งเน้นไปที่การเชื่อมต่ออย่างสมบูรณ์ เมื่อระบบจำเป็นต้องได้รับการ refactored จำนวนการเขียนโค้ดจะลดลงอย่างมาก การฉีดพึ่งพาทำให้ถั่วและถั่วจัดในไฟล์การกำหนดค่าแทนที่จะเป็น hardcoded เข้าใจการฉีดพึ่งพา
การฉีดพึ่งพาและการผกผันของการควบคุมเป็นแนวคิดเดียวกัน ความหมายเฉพาะคือ: เมื่อบทบาท (อาจเป็นอินสแตนซ์ Java ผู้โทร) ต้องการความช่วยเหลือจากบทบาทอื่น (อินสแตนซ์ Java อื่นผู้โทร) ในกระบวนการเขียนโปรแกรมแบบดั้งเดิมผู้โทรมักจะสร้างขึ้นโดยผู้โทร แต่ในฤดูใบไม้ผลิการทำงานของการสร้าง Callee ไม่ได้ทำโดยผู้โทรอีกต่อไปดังนั้นจึงเรียกว่าการผกผันควบคุม การทำงานของการสร้างอินสแตนซ์ของ Callee มักจะทำโดยภาชนะสปริงแล้วฉีดเข้าไปในผู้โทรดังนั้นจึงเรียกว่าการฉีดพึ่งพา
ไม่ว่าจะเป็นการฉีดขึ้นอยู่กับการพึ่งพาหรือการผกผันควบคุมหมายความว่าฤดูใบไม้ผลิใช้วิธีการแบบไดนามิกและยืดหยุ่นในการจัดการวัตถุต่าง ๆ การใช้งานเฉพาะระหว่างวัตถุมีความโปร่งใสซึ่งกันและกัน
2. แนวคิดของ IOC และ DI
* IOC - ผกผันของการควบคุม, การผกผันควบคุม, กลับด้านขวาของการสร้างของวัตถุไปยังฤดูใบไม้ผลิ! -
* DI - การฉีดพึ่งพาการฉีดพึ่งพาเมื่อกรอบฤดูใบไม้ผลิมีหน้าที่ในการสร้างวัตถุถั่วการฉีดวัตถุพึ่งพาอาศัยกันแบบไดนามิกลงในส่วนประกอบถั่ว! -
3. การสาธิต
สำหรับตัวแปรสมาชิกในชั้นเรียนมีวิธีการฉีดทั่วไปสองวิธี
การฉีดวิธีการตั้งค่าวิธีการฉีดและวิธีการสร้างตัวสร้าง
ก่อนอื่นแสดงประเภทแรก: วิธีการชุดคุณสมบัติการฉีด
1) เลเยอร์ถาวร
แพ็คเกจ com.clj.demo3; Public Class CustomerDaoimpl {โมฆะสาธารณะบันทึก () {system.out.println ("ฉันเป็น dao ของเลเยอร์การคงอยู่"); -2) เลเยอร์ธุรกิจ
หมายเหตุ: ในเวลานี้ฉันต้องการฉีดเลเยอร์การคงอยู่ลงในเลเยอร์ธุรกิจและส่งมอบทางด้านขวาเพื่อสร้างอินสแตนซ์เลเยอร์การคงอยู่ไปยังเฟรมเวิร์กเงื่อนไขคือเลเยอร์ธุรกิจจะต้องจัดเตรียมแอตทริบิวต์สมาชิกและวิธีการตั้งค่าของเลเยอร์การคงอยู่
แพ็คเกจ com.clj.demo3;/** * การฉีดขึ้นอยู่กับการฉีดพึ่งพาเลเยอร์ Dao ลงในชั้นบริการ * @author ผู้ดูแลระบบ * */คลาสสาธารณะ customererviceimpl {// ให้จักรราศี โมฆะสาธารณะ SetCustomerDao (CustomerDaoimpl CustomerDao) {this.customerdao = customerDao; } โมฆะสาธารณะบันทึก () {system.out.println ("ฉันเป็นบริการ ... "); // 1. วิธีดั้งเดิม // ใหม่ CustomerDaoimpl (). บันทึก (); //2.spring วิธี IOC customerdao.save (); -3) การกำหนดค่าการกำหนดค่าไฟล์
<!-การฉีดพึ่งพาการสาธิต-> <bean id = "customerdao"/> <bean id = "ลูกค้าบริการ"> <!-ฉีด dao ลงในเลเยอร์บริการ-> <property name = "customerdao" ref = "customerdao"> </property>
4) ทดสอบ
/** * วิธีการฉีดพึ่งพาสปริง * ฉีดเลเยอร์ DAO ลงในเลเยอร์บริการ */@Test โมฆะสาธารณะ run2 () {// สร้างโรงงานโหลดไฟล์การกำหนดค่าและการสร้างลูกค้าจะถูกสร้างขึ้นดังนั้นการสร้าง customerDao ApplicationContext บริบท = ใหม่ classPathxMlApplicationContext ( CustomerServiceImpl CSI = (CustomerServiceImpl) บริบท. GetBean ("CustomerService"); csi.save (); -ประเภทที่สอง: การฉีดวิธีการก่อสร้าง
1) คลาส Pojo และให้วิธีการสร้าง
แพ็คเกจ com.clj.demo4;/** * วิธีการฉีดสาธิต * @author Administrator * */คลาสสาธารณะ car1 {สตริงส่วนตัว cname; ราคาสองเท่าส่วนตัว Public Car1 (String cname, ราคาสองเท่า) {super (); this.cname = cname; this.price = ราคา; } @Override สตริงสาธารณะ toString () {return "car1 [cname =" + cname + ", price =" + price + "]"; -2) การกำหนดค่าไฟล์การกำหนดค่า
<!-แสดงวิธีการฉีดวิธีการก่อสร้าง-> <bean id = "car1"> <!-วิธีการเขียน 1 <constructor-arg name = "cname" value = "bmw"/> <constructor-arg name = "price" value = "400000"/>-> value = "400000"/> </ebean>
3) ทดสอบ
@Test โมฆะสาธารณะ Run1 () {ApplicationContext AC = ใหม่ classPathxMlApplicationContext ("ApplicationContext.xml"); Car1 Car = (Car1) ac.getBean ("Car1"); System.out.println (Car); -ส่วนขยาย: การสร้างวิธีการฉีดวัตถุหนึ่งไปยังอีกวัตถุหนึ่ง
1) คลาส Pojo: วัตถุประสงค์: ฉีดรถในคอลัมน์ด้านบนเป็นมนุษย์และทำให้เป็นหนึ่งในคุณลักษณะ ในชั้นเรียนนี้จะต้องให้คุณลักษณะสมาชิกของรถและต้องจัดทำวิธีการก่อสร้างแบบพารามิเตอร์
แพ็คเกจ com.clj.demo4; บุคคลระดับสาธารณะ {ชื่อสตริงส่วนตัว; CAR1 ส่วนตัว Car1; บุคคลสาธารณะ (ชื่อสตริง, car1 car1) {super (); this.name = ชื่อ; this.car1 = car1; } @Override สตริงสาธารณะ toString () {return "person [name =" + name + ", car1 =" + car1 + "]"; -2) ไฟล์กำหนดค่า
<!-constructor-arg name = "name" value = "Jaxiansen"/> <constructor-arg name = "car1" ref = "car1"/> </ebean>
4. วิธีการฉีดอาร์เรย์คอลเลกชัน
1) กำหนดคลาส pojo
แพ็คเกจ com.clj.demo4; นำเข้า java.util.arrays; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า java.util.properties; นำเข้า java.util.set;/** * แสดงวิธีการตั้งค่าการฉีด * @author ผู้ใช้ รายการส่วนตัว <String> รายการ; ชุดส่วนตัว <String> ชุด; แผนที่ส่วนตัว <สตริงสตริง> แผนที่; Private Properties Pro; โมฆะสาธารณะ SetPro (Properties Pro) {this.pro = pro; } setSets โมฆะสาธารณะ (ตั้งค่า <string> sets) {this.sets = sets; } โมฆะสาธารณะ setMap (แผนที่ <สตริง, สตริง> แผนที่) {this.map = แผนที่; } โมฆะสาธารณะ setlist (รายการ <String> รายการ) {this.list = list; } โมฆะสาธารณะ setArrs (สตริง [] arrrs) {this.arrs = arrrs; } @Override สตริงสาธารณะ toString () {return "ผู้ใช้ [arrs =" + arrays.toString (arrs) + ", list =" + list + ", set =" + sets + ", map =" + map + ", pro =" + pro + "]"; -2) ไฟล์กำหนดค่า
<!-ชุดการฉีด-> <bean id = "ผู้ใช้"> <!-array-> <property name = "arrs"> <list> <value> number1 </value> <dance> number2 </alues> <value> number3 </value> </list> </property> <! </คุณสมบัติ> <!-ตั้งค่า-> <property name = "sets"> <set> <value> haha </value> <value> haha </value> </set> </property> <!-Set-> <property name = "map"> <perting> <entry = "aa" value = "Rainbow" <property name = "pro"> <props> <prop key = "username"> root </prop> <prop key = "รหัสผ่าน"> 123 </prop> </props> </property> </ebean>
3) ทดสอบ
/ *** ชุดทดสอบการฉีดยา*/ @Test โมฆะสาธารณะ run3 () {ApplicationContext AC = ใหม่ classPathxMlApplicationContext ("ApplicationContext.xml"); ผู้ใช้ผู้ใช้ = (ผู้ใช้) ac.getBean ("ผู้ใช้"); System.out.println (ผู้ใช้); -5. วิธีการพัฒนาในโมดูล
เพิ่มแท็ก <port> ไปยังไฟล์การกำหนดค่าหลัก (สมมติว่าไฟล์กำหนดค่า ApplicationContext2.xml ถูกกำหนดภายใต้แพ็คเกจ com.clj.test)
<!-แนะนำไฟล์การกำหนดค่าอื่น ๆ โดยการพัฒนาโมดูล-> <import Resource = "com/clj/test/ApplicationContext2.xml"/>
1. การเริ่มต้น
1). import jar package
นอกเหนือจาก 6 แพ็คเกจก่อนหน้านี้คุณยังต้องมีแพ็คเกจ Spring-Aop เพื่อเล่นคำอธิบายประกอบ
2). เลเยอร์การคงอยู่และเลเยอร์การใช้งาน (อินเทอร์เฟซถูกละเว้นที่นี่)
เลเยอร์ถาวร
แพ็คเกจ com.clj.demo1; นำเข้า org.springframework.context.annotation.scope; นำเข้า org.springframework.stereotype.component; นำเข้า org.springframework.stereotype.repository;/** userdao {@Override โมฆะสาธารณะบันทึก () {system.out.println ("บันทึกไคลเอนต์ .. "); -ชั้นธุรกิจ
แพ็คเกจ com.clj.demo1; นำเข้า javax.annotation.postconstruct; นำเข้า org.springframework.beans.factory.annotation.autowired; นำเข้า org.springframework.beans.factory.annotation.qualifier; org.springframework.stereotype.Component; ผู้ใช้ระดับสาธารณะ userserviceimpl ใช้ผู้ใช้ {@Override โมฆะสาธารณะ Sayshello () {System.out.println ("Hello Spring"); -3). กำหนดไฟล์การกำหนดค่า
ในเวลานี้ข้อ จำกัด จำเป็นต้องเพิ่มข้อ จำกัด บริบทและเพิ่มการสแกนส่วนประกอบ
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: context = "http://www.springframework.org/schema/context" XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-คำจำกัดความของถั่ว-> <! base-package = "com.clj.demo1"/> </ebeans>
4) เพิ่มคำอธิบายประกอบในคลาสการใช้งาน
/*** คำอธิบายประกอบส่วนประกอบซึ่งสามารถใช้เพื่อทำเครื่องหมายคลาสปัจจุบัน* คล้ายกับ <bean id = "userservice">* ค่าหมายถึงการให้นามแฝงสำหรับคลาส*/@component (value = "userservice") คลาสสาธารณะผู้ใช้งาน
5) เขียนการทดสอบ
/ *** วิธีการเพิ่มความคิดเห็น*/ @Test โมฆะสาธารณะ run2 () {ApplicationContext ac = ใหม่ classPathxMlApplicationContext ("ApplicationContext.xml"); Userservice US = (Userservice) AC.GetBean ("Userservice"); US.Sayhello (); -2. เกี่ยวกับการจัดการถั่วคุณลักษณะทั่วไป
1. @component: ส่วนประกอบ (ดำเนินการในชั้นเรียน) คำอธิบายประกอบแบบดั้งเดิมที่สุดมันก็โอเคที่จะเขียนสิ่งนี้สำหรับทุกคลาสที่ต้องการคำอธิบายประกอบมันเป็นเรื่องทั่วไป
2. คำอธิบายประกอบอนุพันธ์สามรายการของ @component มีให้ในฤดูใบไม้ผลิ: (ฟังก์ชั่นมีความสอดคล้องกันในปัจจุบัน)
* @Controller - ทำงานบนเว็บเลเยอร์
* @Service - ทำหน้าที่ในระดับธุรกิจ
* @Repository - ทำหน้าที่ในเลเยอร์การคงอยู่
* หมายเหตุ: คำอธิบายประกอบทั้งสามนี้มีวัตถุประสงค์เพื่อทำให้จุดประสงค์ของคลาสคำอธิบายประกอบชัดเจนและสปริงจะปรับปรุงในรุ่นต่อ ๆ ไป
3. คำอธิบายประกอบสำหรับการฉีดแอตทริบิวต์ (หมายเหตุ: เมื่อใช้การฉีดคำอธิบายประกอบคุณไม่จำเป็นต้องจัดเตรียมวิธีการ)
* หากเป็นการฉีดประเภทปกติคุณสามารถใช้คำอธิบายประกอบค่าได้
* @Value - สำหรับการฉีดประเภทปกติ
* หากประเภทวัตถุที่ฉีดให้ใช้คำอธิบายประกอบต่อไปนี้
* @autowired - โดยค่าเริ่มต้นประเภทจะถูกประกอบโดยอัตโนมัติตามประเภทและไม่มีส่วนเกี่ยวข้องกับชื่อคลาสของคลาสที่ฉีด
* หากคุณต้องการฉีดตามชื่อ
* @qualifier - บังคับให้ใช้การฉีดชื่อกับ AutoWired ระบุชื่อคลาสและเกี่ยวข้องกับชื่อคลาสที่ฉีด
* @Resource - เทียบเท่ากับ @autowired และ @qualifier
* เน้น: คำอธิบายประกอบที่จัดทำโดย Java
* แอตทริบิวต์ใช้แอตทริบิวต์ชื่อ
4. คำอธิบายประกอบขอบเขตของถั่ว
* หมายเหตุประกอบเป็น @Scope (value = "Prototype") ซึ่งใช้ในชั้นเรียน ค่ามีดังนี้:
* Singleton - Singleton, ค่าเริ่มต้น
* ต้นแบบ - หลายกรณี
5. การกำหนดค่าวงจรชีวิตของถั่ว (เข้าใจ)
* คำอธิบายประกอบมีดังนี้:
* @postConstruct-เทียบเท่ากับ init-method
* @predestroy-เทียบเท่ากับการทำลายวิธีการ
1. แสดงคำอธิบายประกอบวัตถุแอตทริบิวต์
เงื่อนไข: การฉีดแอตทริบิวต์ (ชื่อ) และวัตถุ (userDaoImpl) ลงในเลเยอร์ธุรกิจโดยการสแกน
1) เปิดเลเยอร์การคงอยู่เพื่อสแกนคำอธิบายประกอบ
//@component (value = "userdao") คำอธิบายประกอบคลาสสากล@repository (value = "ud") คลาสสาธารณะ UserDaoimpl ใช้ UserDao {@Override โมฆะสาธารณะบันทึก () {System.out.println ("บันทึกไคลเอนต์ .. "); -2) เลเยอร์ธุรกิจมีคำอธิบายประกอบสำหรับคุณลักษณะและวัตถุ
แพ็คเกจ com.clj.demo1; นำเข้า javax.annotation.postconstruct; นำเข้า org.springframework.beans.factory.annotation.autowired; นำเข้า org.springframework.beans.factory.annotation.qualifier; org.springframework.stereotype.Component;/** * คำอธิบายประกอบส่วนประกอบสามารถใช้เพื่อทำเครื่องหมายคลาสปัจจุบัน * คล้ายกับ <bean id = "userservice"> * ค่าหมายถึงการให้นามแฝงกับคลาส * /// @scope (value = "grototype") UserserVice {// แอตทริบิวต์คำอธิบายประกอบ: เทียบเท่ากับการฉีดสตริงที่ระบุลงในแอตทริบิวต์ชื่อ วิธีการตั้งชื่อสามารถละเว้นได้โดยไม่ต้องเขียน @Value (value = "Jaxiansen") ชื่อสตริงส่วนตัว; /** * วิธีการฉีดอ้างอิง 1: AutoWired () * วิธีการฉีดอ้างอิง 2: AutoWired () + ผู้คัดเลือก * วิธีการฉีดอ้างอิง 3: @Resource (name = "userdao") วิธี Java, ระบุการฉีดตามชื่อ * // // AutoWired () @qualifier (value = "ud") // การฉีดตามชื่อจะต้องใช้กับ AutoWired ทั้งสองสามารถระบุ UserDao ผู้ใช้ส่วนตัวคลาสส่วนตัว; // โปรดทราบว่าค่าในรอบคัดเลือกเป็นชื่อคำอธิบายประกอบที่ด้านบนของชื่อคลาส UserDaoimpl หรือคุณสามารถระบุชื่อ ID ของถั่วในไฟล์กำหนดค่า/*โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; }*/ @Override โมฆะสาธารณะ sayshello () {system.out.println ("สวัสดีสปริง"+ชื่อ); userdao.save (); } // @postConstruct แท็กคำอธิบายประกอบสำหรับการเริ่มต้นในการดำเนินการ lifecycle @PostConstruct โมฆะสาธารณะ init () {system.out.println ("เริ่มต้น ... "); -3) ไฟล์การกำหนดค่าจะต้องเปิดใช้งานเพื่อสแกนไฟล์การกำหนดค่าทั้งหมดเท่านั้น
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: context = "http://www.springframework.org/schema/context" XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-คำจำกัดความของถั่ว-> <! base-package = "com.clj.demo1"/> </ebeans>
หมายเหตุ: สำหรับคอลเลกชันขอแนะนำให้ใช้ไฟล์การกำหนดค่า
2. Framework Spring รวมการทดสอบหน่วย Junit
1) เพิ่มแพ็คเกจการพึ่งพาที่ต้องการในสปริงทดสอบ
หมายเหตุ: myeclipes มาพร้อมกับสภาพแวดล้อม Junit ของตัวเอง แต่บางครั้งเนื่องจากปัญหาเวอร์ชันอาจจำเป็นต้องมีสภาพแวดล้อม Junit ใหม่ ที่นี่ฉันได้ดาวน์โหลดแพ็คเกจ Junit-4.9 JAR ใหม่ออนไลน์ หาก myeclipes ใหม่กว่าคุณไม่จำเป็นต้องพิจารณา
2) เขียนคลาสทดสอบและเพิ่มคำอธิบายประกอบที่สอดคล้องกัน
@Runwith และ @ContextConfiguration (ใช้ในการโหลดไฟล์การกำหนดค่าเนื่องจากเส้นทางเริ่มต้นจาก WebRoot เป็นไดเรกทอรีระดับแรกรวมถึงนี่คือการพิจารณาว่า SRC เป็นไดเรกทอรีระดับแรก)
แพ็คเกจ com.clj.demo2; นำเข้า Javax.annotation.resource; นำเข้า org.junit.test; นำเข้า org.junit.runner.runwith; นำเข้า org.springframework.test.context.contextconfiguration; com.clj.demo1.userservice; @runwith (springjunit4classrunner.class) @contextconfiguration ("classpath: applicationcontext.xml") คลาสสาธารณะ demo2 {@resource (name = "userservice") ผู้ใช้ส่วนตัว @Test โมฆะสาธารณะ run1 () {userservice.sayhello (); -6. AOP of Spring Framework
1. AOP คืออะไร
* ในอุตสาหกรรมซอฟต์แวร์ AOP เป็นตัวย่อของการเขียนโปรแกรมที่มุ่งเน้นด้านความหมาย: การเขียนโปรแกรม Facet, การทำงานแบบแยกส่วน
* AOP เป็นกระบวนทัศน์การเขียนโปรแกรมซึ่งเกี่ยวข้องกับหมวดหมู่ของงานอ่อนนุ่มแนะนำนักพัฒนาวิธีการจัดระเบียบโครงสร้างโปรแกรม
* AOP ถูกเสนอครั้งแรกโดยองค์กร AOP Alliance และกำหนดชุดของบรรทัดฐาน ฤดูใบไม้ผลิแนะนำแนวคิด AOP เข้าสู่กรอบและต้องปฏิบัติตามข้อกำหนดของ AOP Alliance
* เทคโนโลยีเพื่อให้ได้การบำรุงรักษาฟังก์ชั่นโปรแกรมแบบครบวงจรผ่านการรวบรวมล่วงหน้าและตัวแทนแบบไดนามิกในระหว่างการรันไทม์
* AOP เป็นความต่อเนื่องของ OOP หัวข้อร้อนแรงในการพัฒนาซอฟต์แวร์ส่วนสำคัญของกรอบฤดูใบไม้ผลิและกระบวนทัศน์อนุพันธ์ของการเขียนโปรแกรมที่ใช้งานได้
* การใช้ AOP ส่วนต่าง ๆ ของตรรกะทางธุรกิจสามารถแยกได้ซึ่งจะช่วยลดการมีเพศสัมพันธ์ระหว่างส่วนของตรรกะทางธุรกิจการปรับปรุงความสามารถในการใช้ซ้ำของโปรแกรมและปรับปรุงประสิทธิภาพของการพัฒนา
AOP ใช้กลไกการสกัดแนวนอนแทนที่รหัสซ้ำ ๆ ของระบบสืบทอดแนวตั้งแบบดั้งเดิม (การตรวจสอบประสิทธิภาพการจัดการธุรกรรมการตรวจสอบความปลอดภัยการแคช)
2. ทำไมต้องศึกษา AOP
* โปรแกรมสามารถปรับปรุงได้โดยไม่ต้องแก้ไขซอร์สโค้ด! - (สร้างพร็อกซีสำหรับวิธีการคงที่ก่อนที่จะเข้าถึงวิธีการป้อนพร็อกซีก่อนในพร็อกซีคุณสามารถเขียนฟังก์ชั่นเพิ่มเติมเพื่อให้วิธีการที่มีประสิทธิภาพยิ่งขึ้นและปรับปรุงโปรแกรม)
AOP: การเขียนโปรแกรมแบบมุ่งเน้น, โมดูลทุกอย่างโมดูลแต่ละโมดูลนั้นค่อนข้างอิสระโมดูลสามารถใช้ร่วมกันได้ (เหมือนกัน) และแตกต่างกันโดยเฉพาะอย่างยิ่ง ใช้สิ่งนี้แทนการเขียนโปรแกรมแนวตั้งแบบดั้งเดิมเพื่อปรับปรุงความสามารถในการนำโปรแกรมกลับมาใช้ใหม่
3. การใช้งาน AOP (หลักการดำเนินการ)
การใช้งานของ AOP นั้นมีวิธีการพร็อกซีสองวิธี <1> ในการใช้อินเทอร์เฟซคลาส: ใช้ JDK Dynamic Proxy <2> ไม่ได้ใช้งานอินเตอร์เฟสคลาส: ใช้ CGLIB Dynamic Proxy
1. ใช้พร็อกซีไดนามิก JDK
1) กำหนดคลาสการใช้งานอินเทอร์เฟซเลเยอร์การคงอยู่
แพ็คเกจ com.clj.demo3; อินเตอร์เฟสสาธารณะ userdao {โมฆะสาธารณะบันทึก (); การอัปเดตโมฆะสาธารณะ ();} แพ็คเกจ com.clj.demo3; คลาสสาธารณะ userdaoimpl ใช้ userdao {@Override โมฆะสาธารณะบันทึก () {system.out.println ("บันทึกผู้ใช้"); } @Override โมฆะสาธารณะอัปเดต () {system.out.println ("แก้ไขผู้ใช้"); -2) กำหนดคลาสเครื่องมือพร็อกซีไดนามิก JDK ไดนามิก
คลาสเครื่องมือนี้เพิ่มฟังก์ชั่นบางอย่างเมื่อดำเนินการวิธีการบันทึกเลเยอร์การคงอยู่และในการพัฒนามีความจำเป็นต้องปรับปรุงวิธีการบางอย่างโดยไม่ต้องเปลี่ยนซอร์สโค้ด
แพ็คเกจ com.clj.demo3; นำเข้า java.lang.reflect.invocationhandler; นำเข้า java.lang.reflect.method; นำเข้า java.lang.reflect.proxy;/** * สร้างวัตถุพร็อกซีใน JDK getProxy (ขั้นสุดท้าย userdao dao) {// ใช้คลาสพร็อกซีเพื่อสร้างวัตถุพร็อกซี userdao proxy = (userdao) proxy.newproxyinstance (dao.getClass (). getClassLoader (), dao.getClass () จะถูกดำเนินการเมื่อวัตถุสาธารณะเรียกใช้ (พร็อกซีวัตถุ, วิธีการ, วัตถุ [] args) โยน {// พร็อกซีแสดงถึงวัตถุพร็อกซีปัจจุบัน // เมธอดเมธDที่ดำเนินการโดยวัตถุปัจจุบัน // args พารามิเตอร์ที่ห่อหุ้ม // ให้การบันทึกหรือการอัพเดท method.invoke (dao, args);}}); ส่งคืนพร็อกซี; -3) ทดสอบ
แพ็คเกจ com.clj.demo3; นำเข้า org.junit.test; คลาสสาธารณะ demo1 {@test โมฆะสาธารณะ run1 () {// รับวัตถุเป้าหมาย userdao dao = ใหม่ userdaoimpl (); dao.save (); dao.update (); System.out.println ("================================================================================================================== - ใช้คลาสเครื่องมือเพื่อรับพร็อกซีอ็อบเจ็กต์ผู้ใช้ proxy = myproxyutils.getproxy (DAO);2. ใช้เทคโนโลยี CGLIB
1) กำหนดเลเยอร์การคงอยู่ไม่มีอินเทอร์เฟซในเวลานี้
แพ็คเกจ com.clj.demo4; ชั้นเรียนสาธารณะ BookDaoimpl {โมฆะสาธารณะบันทึก () {System.out.println ("บันทึกหนังสือ"); } การอัปเดตโมฆะสาธารณะ () {system.out.println ("แก้ไขหนังสือ"); -2) การเขียนคลาสเครื่องมือ
แพ็คเกจ com.clj.demo4; นำเข้า java.lang.reflect.method; นำเข้า org.springframework.cglib.proxy.enhancer; นำเข้า org.springframework.cglib.proxy.methodinterceptor; CGLIB Method * @author Administrator * */คลาสสาธารณะ MyCgliblys {/** * สร้างวัตถุพร็อกซีโดยใช้วิธี cGlib * @return */สาธารณะ bookdaoimpl getProxy () {enhancer enhancer = ใหม่เพิ่มประสิทธิภาพ (); // ตั้งค่าคลาสแม่แบบเพิ่มระดับ SetsuperClass (bookdaoimpl.class); // ตั้งค่าฟังก์ชั่น callback enhancer.setCallback (New MethodInterceptor () {@Override การสกัดกั้นวัตถุสาธารณะ (Object OBJ, วิธีการ, วัตถุ [] OBJS, MethodProxy MethodProxy) การโยน {ถ้า method.getName () exe ("บันทึก") } return methodproxy.invokesuper (obj, objs); // เป็นวิธีที่ดำเนินการ}}); // สร้างพร็อกซีออบเจ็กต์ bookdaoimpl พร็อกซี = (bookdaoimpl) enhancer.create (); ส่งคืนพร็อกซี; -3) เขียนคลาสทดสอบ
แพ็คเกจ com.clj.demo4; นำเข้า org.junit.test; คลาสสาธารณะ demo1 {@test โมฆะสาธารณะ run1 () {// เป้าหมายวัตถุ bookdaoimpl dao = ใหม่ bookdaoimpl (); dao.save (); dao.update (); System.out.println ("=================================); bookdaoimpl พร็อกซี = mycglibutils.getproxy (); proxy.save (); proxy.update ();}};3. การพัฒนา AOP ของ Spring ตาม ASPASTJ (วิธีการกำหนดค่าไฟล์)
1) ปรับใช้สภาพแวดล้อมและนำเข้าแพ็คเกจ JAR ที่เกี่ยวข้อง
2) สร้างไฟล์การกำหนดค่าและแนะนำข้อ จำกัด ของ AOP
<ถั่ว xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.aop.xsd
3) สร้างอินเทอร์เฟซและใช้คลาส
แพ็คเกจ com.clj.demo5; อินเทอร์เฟซสาธารณะ customerdao {โมฆะสาธารณะบันทึก (); การอัปเดตโมฆะสาธารณะ ();} แพ็คเกจ com.clj.demo5;/** * ใช้ไฟล์กำหนดค่าเพื่อตีความ AOP * @Author Administrator * */Class Public CustomerDaoImpl ดำเนินการลูกค้า {@Override โมฆะสาธารณะบันทึก () {// จำลองข้อยกเว้น // int a = 10/0; System.out.println ("บันทึกลูกค้า"); } @Override โมฆะสาธารณะอัปเดต () {// todo วิธีการที่สร้างอัตโนมัติระบบ Stub System.out.println ("อัปเดตลูกค้า"); -4) กำหนดคลาส facet
แพ็คเกจ com.clj.demo5; นำเข้า org.aspectj.lang.proceedingjoinpoint;/** * คลาส facet: จุดเข้า + การแจ้งเตือน * @author ผู้ดูแลระบบ * */คลาสสาธารณะ myaspectxml {/** * การแจ้งเตือน } / ** * วิธีการดำเนินการสำเร็จหรือข้อยกเว้นจะถูกดำเนินการ * / โมฆะสาธารณะหลังจาก () {system.out.println ("การแจ้งเตือนขั้นสุดท้าย"); } /*** หลังจากดำเนินการวิธีการการแจ้งเตือนโพสต์จะถูกดำเนินการ หากข้อยกเว้นเกิดขึ้นในโปรแกรมการแจ้งเตือนโพสต์จะไม่ถูกเรียกใช้งาน */ โมฆะสาธารณะ afterreturn () {system.out.println ("การแจ้งเตือนโพสต์"); } / ** * หลังจากวิธีการถูกดำเนินการหากมีข้อยกเว้นการแจ้งเตือนข้อยกเว้นจะถูกดำเนินการ * / โมฆะสาธารณะหลังการเทียม () {system.out.println ("การแจ้งเตือนข้อยกเว้น"); } /*** การแจ้งเตือนรอบตัว: การแจ้งเตือนเกิดขึ้นก่อนและหลังวิธีการถูกดำเนินการ * โดยค่าเริ่มต้นวิธีการของวัตถุเป้าหมายไม่สามารถดำเนินการได้และวัตถุเป้าหมายจะต้องดำเนินการด้วยตนเอง */ โมฆะสาธารณะรอบ ๆ // ให้วิธีการของวัตถุเป้าหมายดำเนินการลอง {joinpoint.proceed (); } catch (throwable e) {// todo บล็อก catch block ที่สร้างอัตโนมัติ e.printstacktrace (); } system.out.println ("การแจ้งเตือนห่อ 2"); -5) คลาสการใช้งานและคลาส facet
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <! id="myAspectXml"/> <!-- Configure the section class --> <bean id="myAspectXml"/> <!-- Configure the section class: entry point + notification (type) --> <aop:aspect ref="myAspectXml"> <!-- Configure the pre-notification, and the enhancement method will be executed before the save method is executed --> <!-- Point cutting expression: execution(public void com.clj.demo5.CustomerDaoImpl.save()) --> <!-- Point cutting expression: 1.execution() is fixed, must be written 2.public can be omitted and not written 3. The return value must be written, strictly based on the point cutting method, otherwise the enhancement method will not be executed, and it can be replaced by * to represent any return value 4. The package name must be written, and it can be replaced by * (such as: *..* (default all packages); com.clj.*) 5. The class name must be written. You can partially use * (such as *DaoImpl means a persistent layer implementation class ending with 'DaoImpl'), but it is not recommended to use * instead of the entire class name 6. The method must be written. You can partially use * (such as save* means a method starting with 'save'), but it is not recommended to use * instead of the entire class name 7. The method parameters are determined according to the actual method, and you can use '..' to indicate that there are 0 or more parameters --> <!-- <aop:before method="log" pointcut="execution(public void com.clj.*.CustomerDaoImpl.save(..))"/> --> <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save*(..))"/> </aop:aspect> </aop:config></beans>
6)测试
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="customerDao") private CustomerDao customerDao; @Test public void run(){ customerDao.save(); customerDao.update(); -扩展:切面类升级
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <bean id="myAspectXml"/> <aop:config> <aop:aspect ref="myAspectXml"> <!-- Configure final notification<aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>-- Configure post-notification<aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- Configuration exception notification<aop:after-throwing method="afterThrowing" pointcut="execution(* *..*.*.DaoImpl.save*(..))"/>--> <aop:around method="around" pointcut="execution(* *..*.*.DaoImpl.update*(..))"/> </aop:aspect> </aop:config></beans>
4、Spring框架AOP之注解方式
1)创建接口和实现类
package com.clj.demo1;public interface CustomerDao { public void save(); public void update();} package com.clj.demo1;public class CustomerDaoImpl implements CustomerDao{ @Override public void save() { // TODO Auto-generated method stub System.out.println("Save customer.."); } @Override public void update() { // TODO Auto-generated method stub System.out.println("Update customer"); -2)定义切面类
package com.clj.demo1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;/** * 注解方式的切面类* @Aspect表示定义为切面类*/@Aspectpublic class MyAspectAnno { //通知类型:@Before前置通知(切入点的表达式) @Before(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void log(){ System.out.println("记录日志。。"); } //引入切入点@After(value="MyAspectAnno.fun()") public void after(){ System.out.println("执行之后"); } @Around(value="MyAspectAnno.fun()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("环绕通知1"); try { //让目标对象执行joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("环绕通知2"); } //自定义切入点@Pointcut(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void fun(){ }}3)配置切面类和实现类,并开启自动代理
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Turn on the automatic annotation proxy --> <aop:aspectj-autoproxy/> <!-- Configure the target object --> <bean id="customerDao"/> <!-- Configure the facet class --> <bean id="myAspectAnno"/></beans>
spring提供了JDBC模板:JdbcTemplate类
1.快速搭建
1)部署环境
这里在原有的jar包基础上,还要添加关乎jdbc的jar包,这里使用的是mysql驱动
2)配置内置连接池,将连接数据库程序交给框架管理,并配置Jdbc模板类
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Configure the connection pool first (built-in) --> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- Configure the template class for JDBC --> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean></beans>
3)测试
package com.clj.demo2;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import javax.annotation.Resource;import org.apache.commons.dbcp.BasicDataSource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.cglib.beans.BeanMap;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * 测试JDBC的模板类,使用IOC的方式* @author Administrator * */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; /** * 插入*/ @Test public void run1(){ String sql="insert into t_account values(null,?,?)"; jdbcTemplate.update(sql,"李钇林",10000); } /** * 更新*/ @Test public void run2(){ String sql="update t_account set name=? where id=?"; jdbcTemplate.update(sql,"李钇林",1); } /** * 删除*/ @Test public void run3(){ String sql="delete from t_account where id=?"; jdbcTemplate.update(sql,4); } /** * 测试查询,通过主键来查询一条记录*/ @Test public void run4(){ String sql="select * from t_account where id=?"; Account ac=jdbcTemplate.queryForObject(sql, new BeanMapper(),1); System.out.println(ac); } /** * 查询所有*/ @Test public void run5(){ String sql="select * from t_account"; List<Account> ac=jdbcTemplate.query(sql,new BeanMapper()); System.out.println(ac); }}/** * 定义内部类(手动封装数据(一行一行封装数据,用于查询所有) * @author Administrator * */class BeanMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account ac=new Account(); ac.setId(rs.getInt("id")); ac.setName(rs.getString("name")); ac.setMoney(rs.getDouble("money")); return ac; } }2、配置开源连接池
一般现在企业都是用一些主流的连接池,如c3p0和dbcp
首先配置dbcp
1)导入dbcp依赖jar包
2)编写配置文件
<!-- 配置DBCP开源连接池--> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
配置c3p0
1)导入c3p0依赖jar包
2)配置c3p0
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
1、什么是事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
2、怎么解决事务安全性问题
读问题解决,设置数据库隔离级别;写问题解决可以使用悲观锁和乐观锁的方式解决
3、快速开发
方式一:调用模板类,将模板注入持久层
1)编写相对应的持久层和也外层,这里省略接口
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ // Method 1: Inject the jdbc template class into the configuration file and write the template class private in the persistence layer JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void outMoney(String out, double money) { String sql="update t_account set money=money-? where name=?"; jdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; jdbcTemplate().update(sql,money,in); - package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); -2)配置相对应的配置文件
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- Configuring the C3P0 open source connection pool--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean><!-- Configure the template class of JDBC --> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean><!-- Configure the business layer and persistence layer --> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean><bean id="accountDao"> <!-- Inject the template class --> <property name="jdbcTemplate" ref="jdbcTemplate"/> <property name="dataSource" ref="dataSource"/> </bean></beans>
3)测试类
package com.clj.demo3;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); -方式二:持久层继承JdbcDaoSupport接口,此接口封装了模板类jdbcTemplate
1)编写配置文件
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Configure C3P0 open source connection pool--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- Configure the business layer and persistence layer--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)更改持久层
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); -3)更改业务层
package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); -4)测试类和上述一样
4、spring事务管理
In order to simplify transaction management code, Spring provides a template class TransactionTemplate, which can be manually programmed to manage transactions. You only need to use this template class! -
1、手动编程方式事务(了解原理)
1)快速部署,搭建配置文件,配置事务管理和事务管理模板,并在持久层注入事务管理模板
配置事务管理器
<!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务管理模板
<bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/></bean>
将管理模板注入业务层
<bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/></bean>
全部代码:
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Configure C3P0 open source connection pool--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- Configure the business layer and persistence layer--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean> <!-- Configure the platform transaction manager--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- Configure the platform transaction manager--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- Manual encoding method, providing a template class, using this class to manage transactions is simpler --> <bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean></beans>
2)在业务层使用模板事务管理
package com.clj.demo3;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //Usage configuration file injection method, set method must be provided private AccountDao accountDao; //Inject transaction template class private TransactionTemplate transactionTemplate; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } /** * Method of transfer*/ public void pay(final String out,final String in, final double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { //The execution of the transaction, if there is no problem, submit, if Chu Xiang is exception, roll back protected void doInTransactionWithoutResult(TransactionStatus arg0) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }); -3)测试类和上一致
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); -申明式事务有两种方式:基于AspectJ的XML方式;基于AspectJ的注解方式
1、XML方式
1)配置配置文件
需要配置平台事务管理
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务增强
<tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
aop切面类
<aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config>
全部代码
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Configure C3P0 open source connection pool--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- Configure platform transaction manager --> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- Declaration transaction (using XML file method) --> <!-- Configure notifications first-> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- Set database attributes for the method (isolation level, propagation behavior) --> <!-- Propagation transaction isolation level: generally use the default form: tx:method can set multiple --> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- Configure AOP: If it is an AOP written by yourself, use aop:aspect configuration, use notifications provided by Spring framework--> <aop:config> <!-- aop:advisor, is notifications provided by spring framework--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config> <!-- Configure business layer and persistence layer--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)编写持久层和业务层(省略接口)
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); - package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //It uses configuration file injection method, and the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); -3)测试类
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); -2、注解方式
1)配置配置文件
配置事务管理
<bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
开启注释事务
<!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
全部代码
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Configure C3P0 open source connection pool--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- Configure platform transaction manager--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- Open transaction annotation-driven transaction-manager="transactionManager"/> <!-- Configure business layer and persistence layer--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)业务层增加@Transactional
package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;//Add this annotation in the current class means that all the current class has transactions @Transactionalpublic class AccountServiceImpl implements AccountService{ //Using configuration file injection method, the set method must be provided private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); -3)持久层不变
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //Method 1: Inject the jdbc template class into the configuration file and write the template class directly in the persistence layer// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } // Method 2: The persistence layer inherits JdbcDaoSupport, which encloses the template class. The persistence layer of the configuration file does not need to inject the template class, nor does it need to configure the template class public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); -4)测试类
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext3.xml")public class Demo3 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //Call the payment method accountService.pay("Jia Xiansen","Li Yilin",100); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น