يتم إنشاء إطار الربيع بسبب تعقيد تطوير البرمجيات. يستخدم Spring Javabeans الأساسي للقيام بأشياء كانت ممكنة من قبل فقط بواسطة EJB. ومع ذلك ، لا يقتصر غرض الربيع على تطوير من جانب الخادم. من منظور البساطة ، قابلية الاختبار والاقتران الفضفاض ، يمكن أن تستفيد معظم تطبيقات Java من الربيع. Spring عبارة عن انعكاس تحكم خفيف الوزن (IOC) وإطار حاوية موجه نحو القسم (AOP).
◆ الغرض: حل تعقيد تطوير تطبيق المؤسسة
◆ الوظيفة: استخدم Javabean الأساسي بدلاً من EJB ، ويوفر المزيد من وظائف تطبيق المؤسسة
◆ النطاق: أي تطبيق Java
يعطي انعكاس التحكم (IOC في اختصار اللغة الإنجليزية) الحق في إنشاء كائنات للإطار ، وهو ميزة مهمة في الإطار وليس مصطلحًا خاصًا للبرمجة الموجهة للكائنات. ويشمل الحقن التبعية وبحث التبعية. في طبقة الأعمال التقليدية ، عند الحاجة إلى الموارد ، توجد موارد جديدة في طبقة العمل ، بحيث يكون الاقتران (الترابط والعلاقة بين البرامج) أعلى. الآن سلم الجزء الجديد إلى الربيع لتحقيق التماسك العالي والاقتران المنخفض. باختصار: في الأصل ، كلما تم استدعاء طريقة طبقة DAO أو طبقة الخدمة ، سيستخدم التطبيق جديدًا ، والآن تم تسليم الحقوق الجديدة إلى الربيع ، وما هي الموارد التي تم الحصول عليها من الربيع!
1. قم بتنزيل حزمة جرة التبعية المطلوبة للإطار
موقع الربيع الرسمي هو: http://spring.io/
قم بتنزيل حزمة الجرة: http://repo.springsource.org/libs-release-local/org/springframework
2. استيراد حزمة الجرة الأساسية
في الواقع ، تشمل الجرار الأساسية الأساسية الفاصوليا ؛ السياق ؛ الأساس ؛ حزم التعبير ، والآخر يعتمد على سجلات log4j. بطبيعة الحال ، فإن الجرار الربيعية أكثر من ذلك ، تتم إضافتها ببطء في المرحلة اللاحقة.
3. تكوين ملف تكوين log4j
يتم تعريف ملف السجل في دليل SRC
### رسائل السجل المباشر إلى stdout ### log4j.appender.stdout = org.apache.log4j.consoleAppenderLog4j.appender.stdout.target = system.errlog4j.appender.stdout.layout = org.apache.log4j.patternlayoutlog4j.appender.layout.layout.conversion ٪ C {1}: ٪ l - ٪ m ٪ n ### الرسائل المباشرة لتقديم mylog.log ### log4j.appender.file = org.apache.log4j.fileAppenderLog4j.appender.file = c/: mylog.loglog4j.appender.file.layout = org.apache.log4j.patternlayoutlog4j.appender.file.layout.layout ٪ C {1}: ٪ l - ٪ m ٪ n ### تعيين مستويات السجل - لمزيد من التسجيل المطوّل تغيير "المعلومات" إلى "debug" ### log4j.rotlogger = info ، stdout4. اختبار ما إذا كان يتم نشر ملف السجل بنجاح
package com.clj.demo1 ؛ import org.apache.log4j.logger ؛ import org.junit.test ؛/** * demo demo use * Author Administrator * */public class demo1 {// Create log class private log = logger.getlogger (demo1.class) ؛ test public void run1 () {// قم بتغيير المعلومات في سمة log4j.rootlogger إلى OFF ، و log.info ("execute") ؛ }}5. تحديد واجهة وتنفيذ الفئة
الواجهة:
package com.clj.demo2 ؛ واجهة عامة orseverservice {public void sayhello () ؛}فئة التنفيذ
package com.clj.demo2 ؛ public class userviceImpl تنفذ المستخدمين {اسم السلسلة الخاصة ؛ السلسلة العامة getName () {return name ؛ } public void setName (اسم السلسلة) {this.name = name ؛ } public void init () {system.out.println ("initialize ..") ؛ } public void sealhhello () {system.out.println ("Hello Spring"+"/t"+name) ؛ } public void destory () {system.out.println ("Destroy ..") ؛ }}6. تحديد ملفات التكوين الخاصة بالينابيع
حدد اسم ApplicationContext.xml ، الموقع هو SRC ، وهو نفس الدليل مثل ملف السجل ، واستيراد القيود المقابلة ، وحقن فئة التنفيذ في ملف التكوين. فقط ابدأ بالبداية ، استخدم قيود الفول
<؟ xmlns: p = "http://www.springframework.org/schema/p" <!-استخدم Tag Bean 1. قيمة المعرف فريدة من نوعها (يجب أن تكتب) 2. ملاحظة: الفئة هي فئة التنفيذ ، وليس واجهة (يجب أن تكتب) 3. تهيئة العمل قبل تنفيذ الطريقة الأساسية (حدد الكتابة) 4. عمل التهيئة بعد تنفيذ الطريقة الأساسية (تحديد اسم "> اسم" </bean> </bans>
7. اختبار
الفئة العامة Demo1 { /*** Way Original* /Test Public void Run () {// إنشاء فئة فئة التنفيذ orsterviceImpl s = new UsperServiceImpl () ؛ S.SetName ("Jaxiansen") ؛ S.Sayhello () ؛ } / *** إصدار المصنع القديم BeanFactory* لن يقوم المصنع القديم بإنشاء كائنات ملف التكوين* / test public void run2 () {beanfactory factory = new xmlbeanfactory (classpathresource new ("ApplicationContext.xml") ؛ UserService US = (UserService) Factory.getBean ("UserService") ؛ us.sayhello () ؛ } /*** استخدم Mething Framework IOC Method* إنشاء خادم بدء تشغيل في الإصدار الجديد من المصنع لإنشاء كائن ملف التكوين ، وليس هناك حاجة لتحميل المصنع عند الاتصال مرة أخرى* /test public void run3 () classpathxmlapplicationContext ("ApplicationContext.xml") ؛ // احصل على الكائن من المصنع (قيمة المعرف في ملف التكوين ، يتم استخدام تعدد الأشكال هنا) uservice usi = (UserService) ac.getBean ("uservervice") ؛ // استدعاء طريقة الكائن لتنفيذ usi.sayhello () ؛ ) (تم العثور على classpathxmlapplicationContext ضمن SRC) classPathxMlAppLicationContext ac = classpathxmlapplicationContext ("ApplicationContext.xml") ؛ // احصل على الكائن من المصنع (قيمة المعرف في ملف التكوين ، يتم استخدام تعدد الأشكال هنا) uservice usi = (UserService) ac.getBean ("uservervice") ؛ // استدعاء طريقة الكائن لتنفيذ usi.sayhello () ؛ يوفر فئة تطبيق ApplicationContext طريقة قريبة ، ويمكن إغلاق المصنع ويمكن تنفيذ طريقة الأساليب المصير. }}الفرق بين المصانع القديمة والمصانع الجديدة
* الفرق بين Beanfactory و ApplicationContext
* Beanfactory - Beanfactory يأخذ التحميل كسول ، وسيتم تهيئة الفول فقط عندما تحصل على أول مرة
* ApplicationContext - عند تحميل ApplicationContext.xml ، سيتم إنشاء مثيل محدد لكائن Bean ، ويتم توفير بعض الوظائف الأخرى.
* تسليم الحدث
* تجميع الفول التلقائي
* تطبيقات السياق لطبقات التطبيق المختلفة
ملخص: هذا هو العرض التجريبي الأساسي ، الذي يقوم بتكوين فئة التنفيذ في ملف تكوين الربيع. في كل مرة يتم تشغيل الخادم ، سيتم تحميل ملف التكوين ، وبالتالي إنشاء فئة التنفيذ.
1. ما هو حقن التبعية؟
يمكن أن ينظم الربيع بشكل فعال كائنات من مستويات تطبيق J2EE. سواء كان ذلك هو كائن الإجراء لطبقة التحكم ، أو كائن خدمة طبقة العمل ، أو كائن DAO لطبقة الثبات ، يمكن تنسيقه وتشغيله تحت إدارة الربيع. ينظم الربيع كائنات لكل طبقة معًا بطريقة مقترنة بشكل فضفاض. لا تحتاج كائنات الإجراء إلى الاهتمام بالتنفيذ المحدد لكائنات الخدمة ، ولا تحتاج كائنات الخدمة إلى الاهتمام بالتنفيذ المحدد لكائنات الطبقة المستمرة ، والمكالمات إلى كل كائن طبقة موجهة تمامًا. عندما يحتاج النظام إلى إعادة تمهيد ، سيتم تقليل كمية إعادة كتابة التعليمات البرمجية بشكل كبير. حقن التبعية يجعل الفاصوليا والفاصوليا منظمة في ملفات التكوين ، بدلاً من أن تكون متشددة. فهم حقن التبعية
حقن التبعية وانعكاس التحكم هي نفس المفهوم. المعنى المحدد هو: عندما يحتاج دور (ربما مثيل Java ، المتصل) إلى مساعدة من دور آخر (مثيل Java آخر ، المتصل) ، في عملية البرمجة التقليدية ، يتم إنشاء المتصل عادةً من قبل المتصل. ولكن في فصل الربيع ، لم يعد عمل إنشاء Callee من قبل المتصل ، لذلك يطلق عليه انعكاس التحكم ؛ عادةً ما يتم إجراء عملية إنشاء مثيل Callee بواسطة حاوية الربيع ثم حقنها في المتصل ، لذلك يطلق عليه أيضًا حقن التبعية.
سواء كان حقن التبعية أو انعكاس التحكم ، فهذا يعني أن الربيع يتبنى طريقة ديناميكية ومرنة لإدارة الكائنات المختلفة. التطبيقات المحددة بين الكائنات شفافة مع بعضها البعض.
2. مفهوم IOC و DI
* IOC - عكس التحكم ، الانعكاس السيطرة ، انقلب يمين إنشاء الكائن إلى الربيع! !
* DI - حقن التبعية ، حقن التبعية ، عندما يكون إطار الربيع مسؤولاً عن إنشاء كائنات فول ، وحقن كائنات التبعية ديناميكيًا في مكون الفول! !
3. العرض التوضيحي
بالنسبة للمتغيرات الأعضاء في الفصل ، هناك طريقتان للحقن الشائع.
حقن طريقة مجموعة الممتلكات وحقن طريقة المنشئ
أولا إظهار النوع الأول: حقن طريقة مجموعة الممتلكات
1) طبقة مستمرة
package com.clj.demo3 ؛ clientdaoimpl {public void save () {system.out.println ("أنا داو من طبقة الثبات") ؛ }}2) طبقة العمل
ملاحظة: في هذا الوقت ، أريد حقن طبقة الثبات في طبقة العمل وتسليم الحق في إنشاء مثيل طبقة الثبات إلى الإطار ، والشرط هو أن طبقة العمل يجب أن توفر سمات الأعضاء وطرق طبقة الثبات.
Package com.clj.demo3 ؛/** * حقن الحقن التبعية بطبقة DAO في طبقة الخدمة * Author Administrator * */public clusterviceImpl {// توفير zodiac العضو ، وتوفير طريقة خاصة customerdaoimpl clientdao ؛ public void setCustomerDao (customerdaoimpl customerdao) {this.customerdao = customerDao ؛ } public void save () {system.out.println ("أنا الخدمة ...") ؛ // 1. الطريقة الأصلية // customerdaoimpl () //2.spring ioc method customerdao.save () ؛ }}3) تكوين ملف التكوين
<!-حقن التبعية المظاهرة-> <bean id = "customerdao"/> <bean id = "customerervice"> <!-حقن DAO في طبقة الخدمة-> <property name = "customerdao" ref = "customerdao"> </propert
4) اختبار
/** * طريقة حقن التبعية في الربيع * حقن طبقة DAO في طبقة الخدمة */Test public void run2 () {// إنشاء المصنع ، وتحميل ملف التكوين ، ويتم إنشاء customerervice ، وبالتالي إنشاء customerdao ApplicationContext context = classpathxmlicationContext ("ApplicationContext.xml") ؛ CustomererviceImpl CSI = (CustomererviceImpl) Context.getBean ("customerervice") ؛ csi.save () ؛ }النوع الثاني: حقن طريقة البناء
1) فئة Pojo وتوفير طرق المنشئ
حزمة com.clj.demo4 ؛/** * طريقة الحقن التجريبي * Author Administrator * */public class car1 {private string cname ؛ سعر مزدوج خاص ؛ CAR1 العامة (سلسلة cname ، سعر مزدوج) {super () ؛ this.cname = cname ؛ this.price = السعر ؛ } Override public string toString () {return "car1 [cname =" + cname + "، price =" + price + "]" ؛ }}2) تكوين ملف التكوين
<!-إظهار طريقة حقن طريقة البناء-> <bean id = "car1"> <!-طريقة الكتابة 1 <name constructor-arg = "cname" value = "bmw"/> <constructor-arg name = "price" value = "400000"/>-> <! value = "400000"/> </ban>
3) اختبار
test public void run1 () {applicationContext ac = classpathxmlapplicationContext ("actionContext.xml") ؛ CAR1 CAR = (CAR1) AC.GetBean ("CAR1") ؛ System.out.println (CAR) ؛ }الامتداد: بناء طريقة حقن كائن في آخر
1) فئة Pojo: الغرض: حقن السيارة في العمود أعلاه إلى البشر وجعلها واحدة من السمات. في هذه الفئة ، يجب توفير سمات الأعضاء للسيارة ويجب توفير طرق البناء المعلمة.
Package com.clj.demo4 ؛ public class person {private string name ؛ CAR1 CAR1 الخاص ؛ الشخص العام (اسم السلسلة ، car1 car1) {super () ؛ this.name = name ؛ this.car1 = car1 ؛ } Override Public String ToString () {return "person [name =" + name + "، car1 =" + car1 + "]" ؛ }}2) ملف التكوين
<!-name-arg constructor = "name" value = "jaxiansen"/> <constructor-arg name = "car1" ref = "car1"/> </bean>
4. كيفية حقن مجموعة التجميع
1) تحديد فئة POJO
package com.clj.demo4 ؛ import java.util.arrays ؛ import java.util.list ؛ import java.util.map ؛ import java.util.properties ؛ mypert java.Util.set ؛/** * ** قائمة خاصة <String> ؛ مجموعة خاصة <string> مجموعات ؛ خريطة خاصة <سلسلة ، سلسلة> خريطة ؛ خصائص خاصة المحترفين ؛ public void setPro (properties pro) {this.pro = pro ؛ } setSets public void (set <string> sets) {this.sets = sets ؛ } public void setMap (Map <String ، String> Map) {this.map = map ؛ } public void setlist (list <string> list) {this.list = list ؛ } public void setArrrs (string [] arrrs) {this.arrs = arrrs ؛ } Override Public String ToString () {return "user [arrs =" + arrays.toString (ARRS) + "، list =" + list + "، sets =" + sets + "، map =" + map + "، pro =" + pro + "] ؛ }}2) ملف التكوين
<!-مجموعة الحقن-> <bean id = "user"> <!-Array-> <property name = "arrs"> <list> <suale> number1 </value> <value> number2 </value> <value> number3 </value> </list> </propert </spleneration> <!-SET SET-> <property name = "sets"> <sted> <value> haha </value> <value> haha </value> </stiled> </propert <property name = "pro"> <bors> <prop key = "username"> root </prop> <prop key = "password"> 123 </props> </props> </propert
3) اختبار
/ *** اختبار حقن الاختبار*/ test public void run3 () {applicationContext ac = new ClassPathxMlAppLicationContext ("ApplicationContext.xml") ؛ مستخدم المستخدم = (المستخدم) ac.getBean ("المستخدم") ؛ System.out.println (user) ؛ }5. كيفية التطور في الوحدات النمطية
أضف علامة <Simpl> إلى ملف التكوين الرئيسي (افترض أنه ، يتم تعريف Application Configuration ApplicationContext2.xml ضمن حزمة com.clj.test)
<!-تقديم ملفات التكوين الأخرى عن طريق تطوير الوحدة النمطية-> <import resource = "com/clj/test/applicationContext2.xml"/>
1. البدء
1). حزمة جرة
بالإضافة إلى الحزم الستة السابقة ، تحتاج أيضًا إلى حزمة من الربيع لأوب لتشغيل التعليقات التوضيحية.
2). طبقة الثبات وطبقة التنفيذ (يتم تجاهل واجهات هنا)
طبقة مستمرة
package com.clj.demo1 ؛ استيراد org.springframework.context.annotation.scope ؛ استيراد org.springframework.stereotype.com userDao {Override public void save () {system.out.println ("حفظ العميل ..") ؛ }}طبقة العمل
package com.clj.demo1 ؛ import javax.annotation.postconstruct ؛ import org.springframework.beans.factory.annotation.autowired ؛ mordg.springframework.beans.factory.annotation.Qualifier ؛ org.springframework.stereotype.component ؛ فئة عامة uSperServiceImpl تنفذ المستخدمين {override public void sealhhello () {system.out.println ("hello spring") ؛ }}3). تحديد ملف التكوين
في هذا الوقت ، تحتاج القيود إلى إضافة قيود السياق وإضافة مسح المكون
<؟ xmlns: context = "http://www.springframework.org/schema/context http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan base-package = "com.clj.demo1"/> </beans>
4) إضافة التعليقات التوضيحية إلى فئة التنفيذ
/*** توضيح المكون ، والذي يمكن استخدامه للاحتفال بالفئة الحالية* المشابهة لـ <bean id = "usterveservice">* القيمة تعني إعطاء اسم مستعار للفئة*/@component (value = "userviceervice")
5) كتابة اختبارات
/ *** طريقة التعليقات التوضيحية*/ test public void run2 () {applicationContext ac = new ClassPathxMlAppLicationContext ("ApplicationContext.xml") ؛ UserService US = (UserService) ac.getBean ("userverservice") ؛ us.sayhello () ؛ }2. حول السمات الشائعة لإدارة الفول
1. component: مكون. (تصرف على الفصل) أكثر التعليقات التوضيحية بدائية ، لا بأس في كتابة هذا لجميع الفصول التي تحتاج إلى شرح ، فهو عام
2. يتم توفير ثلاثة شروح مشتقة من component في الربيع: (الوظائف متسقة حاليًا)
* controller - يعمل على طبقة الويب
* service - يعمل على مستوى العمل
* repository - يتصرف على طبقة الثبات
* ملاحظة: تهدف هذه التعليقات التوضيحية الثلاثة إلى جعل الغرض من فئة التعليقات التوضيحية نفسها واضحة ، وسيعززها الربيع في الإصدارات اللاحقة.
3. التعليقات التوضيحية لحقن السمة (ملاحظة: عند استخدام حقن التعليقات التوضيحية ، لا تحتاج إلى توفير طريقة محددة)
* إذا كان نوعًا طبيعيًا من الحقن ، فيمكنك استخدام شرح القيمة
* value - لحقن الأنواع العادية
* إذا كان نوع الكائن المحقن ، فاستخدم التعليق التوضيحي التالي
* Autowired - بشكل افتراضي ، يتم تجميع النوع تلقائيًا حسب النوع ، وليس له أي علاقة باسم الفصل الدراسي للفئة المحقونة.
* إذا كنت تريد الحقن بالاسم
* QALIFIER - يجب استخدام الاستخدام القسري لحقن الاسم مع تلقائي ، حدد اسم الفئة ، ومرتبط باسم الفئة المحقونة
* Resource - أي ما يعادل autowired و Qualifier
* التأكيد: التعليقات التوضيحية التي قدمتها جافا
* تستخدم السمة سمة الاسم
4. التعليق على نطاق الفول
* مشروح كـ scope (value = "النموذج الأولي") ، والذي يتم استخدامه في الفصل. القيم هي كما يلي:
* Singleton - Singleton ، القيمة الافتراضية
* النموذج الأولي - حالات متعددة
5. تكوين دورة حياة الفول (فهم)
* التعليقات التوضيحية كما يلي:
* postconstruct-أي ما يعادل Method
* predestroy-أي ما يعادل تدمير الأساليب
1. إظهار شرح كائن السمة
الشرط: سمات الحقن (الاسم) والكائن (userDaoImpl) في طبقة العمل عن طريق المسح.
1) افتح طبقة الثبات لمسح التوضيح
//@component (value = "userDao") Universal class annotation@ropository (value = "ud") الفئة العامة userDaoImpl تنفذ userdao {Override public void save () {system.out.println ("Save the Client ..") ؛ }}2) توفر طبقة الأعمال تعليقات توضيحية للسمات والكائنات
package com.clj.demo1 ؛ import javax.annotation.postconstruct ؛ import org.springframework.beans.factory.annotation.autowired ؛ mordg.springframework.beans.factory.annotation.Qualifier ؛ org.springframework.stereotype.component ؛/** * * التعليق التوضيحي للمكون ، يمكن استخدامه لتمييز الفئة الحالية * المشابهة لـ <bean id = "userverservice" // سمة شرح السمة: يعادل حقن السلسلة المحددة في سمة الاسم. يمكن حذف طريقة setName دون كتابة Value (value = "jaxiansen") اسم السلسلة الخاصة ؛ /** * طريقة الحقن المرجعية 1: AutoWired () * طريقة الحقن المرجعية 2: AutoWired () + مؤهل * طريقة الحقن المرجعية 3: Resource (name = "userdao") يتم تجميعها تلقائيًا من خلال النوع (لأنها تتطابق مع الأنواع ، لذا ، فهي غير دقيقة للغاية) (). Qalifier (value = "ud") // الحقن بالاسم ، يجب استخدامه مع تلقائي. يمكن كلاهما تحديد الفئة الخاصة userDao userDao ؛ // لاحظ أن القيمة في المؤهل هي اسم التعليقات التوضيحية في الجزء العلوي من اسم فئة userDaoImpl ، أو يمكنك تحديد اسم معرف الفول في ملف التكوين/*public void setName (اسم السلسلة) {this.name = name ؛ }*/ Override public void sayhello () {system.out.println ("hello spring"+name) ؛ userDao.save () ؛ } // postconstruct enootation tag for inivalization in action actioncycle postconstruct public void init () {system.out.println ("initialize ...") ؛ }}3) يجب تمكين ملف التكوين فقط لمسح جميع ملفات التكوين
<؟ xmlns: context = "http://www.springframework.org/schema/context http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan base-package = "com.clj.demo1"/> </beans>
ملاحظة: بالنسبة للمجموعات ، يوصى باستخدام ملفات التكوين
2. إطار الربيع يدمج اختبار وحدة Junit
1) أضف حزمة التبعية المطلوبة
ملاحظة: تأتي Myeclipes مع بيئة Junit الخاصة بها ، ولكن في بعض الأحيان بسبب مشاكل الإصدار ، قد تكون هناك حاجة إلى بيئة Junit جديدة. لقد قمت هنا بتنزيل حزمة JUNIT-4.9 جرة جديدة عبر الإنترنت. إذا كانت Myeclipes أحدث ، فلن تحتاج إلى التفكير فيها.
2) اكتب فئة اختبار وأضف التعليقات التوضيحية المقابلة
Runwith و ContextConfiguration (يتم استخدام هذا لتحميل ملف التكوين ، لأن المسار الافتراضي من Webroot هو دليل من المستوى الأول ، بالإضافة إلى تحديد أن SRC هو دليل من المستوى الأول)
package com.clj.demo2 ؛ import javax.annotation.resource ؛ استيراد org.junit.test ؛ استيراد org.junit.runner.runwith ؛ استيراد org.springframework.test.context.contextConfiguration ؛ import org.springframework.test.test.conit4. com.clj.demo1.userservice ؛@runwith (springJunit4ClassRunner.Class) contextConfiguration ("classPath: ApplicationContext.xml") demo2 {resource (name = "userService") userservice الخاص ؛ test public void run1 () {userService.sayhello () ؛ }}6. Aop of Spring Framework
1. ما هو AOP
* في صناعة البرمجيات ، AOP هو اختصار للبرمجة الموجهة إلى جانب ، المعنى: برمجة الوجه ، الوحدة الوظيفية
* AOP هو نموذج برمجة ، تابع لفئة العمل الناعم ، وتوجيه المطورين كيفية تنظيم هياكل البرنامج
* تم اقتراح AOP لأول مرة من قبل منظمة تحالف AOP وصاغ مجموعة من المعايير. قدم Spring أفكار AOP في الإطار ويجب أن تلتزم بمواصفات تحالف AOP.
* تقنية لتحقيق صيانة موحدة لوظائف البرنامج من خلال الوكلاء المسبق والعوامل الديناميكية أثناء وقت التشغيل
* AOP هو استمرار لـ OOP ، وهو موضوع ساخن في تطوير البرمجيات ، وجزء مهم من إطار الربيع ، ونموذج مشتق للبرمجة الوظيفية.
* باستخدام AOP ، يمكن عزل أجزاء مختلفة من منطق العمل ، مما يقلل من الاقتران بين أجزاء منطق العمل ، وتحسين قابلية استخدام البرنامج ، وتحسين كفاءة التطوير.
يعتمد AOP آلية استخراج أفقية ، لتحل محل الكود المتكرر لنظام الميراث العمودي التقليدي (مراقبة الأداء ، إدارة المعاملات ، فحص الأمان ، التخزين المؤقت)
2. لماذا دراسة AOP
* يمكن تعزيز البرنامج دون تعديل رمز المصدر! ! (قم بإنشاء وكيل لطريقة ثابتة. قبل الوصول إلى الطريقة ، أدخل الوكيل أولاً. في الوكيل ، يمكنك كتابة المزيد من الوظائف لجعل الطريقة أكثر قوة وتعزيز البرنامج)
AOP: البرمجة الموجهة ، تعزز كل شيء ، كل وحدة مستقلة نسبيًا ، يمكن مشاركة الوحدات النمطية (نفسها) ، والمختلف مخصصة بشكل خاص. استخدم هذا بدلاً من البرمجة العمودية التقليدية لتحسين قابلية إعادة استخدام البرنامج
3. تنفيذ AOP (مبدأ التنفيذ)
يتضمن تنفيذ AOP طريقتين وكيل <1> لتنفيذ واجهات الفصل: استخدم JDK Dynamic Proxy <2> واجهات الفئة غير المنفذة: استخدم الوكيل الديناميكي CGLIB
1. تنفيذ الوكيل الديناميكي JDK
1) تحديد فئة تنفيذ واجهة طبقة الثبات
package com.clj.demo3 ؛ واجهة عامة userDao {public void save () ؛ تحديث الفراغ العام () ؛} Package com.clj.demo3 ؛ الفئة العامة userDaoImpl تنفذ userDao {Override public void save () {system.out.println ("حفظ المستخدم") ؛ } Override public void update () {system.out.println ("تعديل المستخدم") ؛ }}2) تحديد فئة أدوات الوكيل الديناميكي JDK
تضيف فئة الأدوات هذه بعض الوظائف عند تنفيذ طريقة حفظ طبقة الثبات ، وفي التطوير ، من الضروري تحسين طريقة دون تغيير رمز المصدر.
package com.clj.demo3 ؛ import java.lang.reflect.invocationHandler ؛ import java.lang.reflect.method ؛ exprate java.lang.reflect.proxy ؛/** * kendate comproxy compuls incloxy stitcy stitcy include (explicate aop) *. getProxy (Final userDao dao) {// استخدم فئة البروكسي لإنشاء كائنات بروكسي userdao proxy = (userDao) proxy.newproxyinstance (dao.getClass (). سيتم تنفيذ الطريقة بمجرد استدعاء الكائن العام (وكيل الكائن ، الطريقة ، الكائن [] args) القابلة للرسوم {// الوكيل يمثل طريقة الكائن الوكيل الحالي//طريقة تم تنفيذها بواسطة الكائن الحالي//args المعلمات المغطاة // المعاملة} طريقة الإرجاع. invoke (dao ، args) ؛ عودة الوكيل. }}3) اختبار
package com.clj.demo3 ؛ import org.junit.test ؛ public class demo1 {test public void run1 () {// الحصول على الكائن الهدف userdao dao = new userDaoimpl () ؛ dao.save () ؛ dao.update () ؛ System.out.println ("================================================================ =============================================================================== استخدم فئة الأدوات للحصول على وكيل الكائن الوسيط = myproxyutils.getproxy (DAO) ؛2. تنفيذ تقنية CGLIB
1) تحديد طبقة الثبات ، لا توجد واجهة في هذا الوقت
package com.clj.demo4 ؛ public class bookdaoimpl {public void save () {system.out.println ("Save Book") ؛ } public void update () {system.out.println ("Modify Book") ؛ }}2) كتابة فصول الأدوات
حزمة com.clj.demo4 ؛ استيراد java.lang.reflect.method ؛ استيراد org.springframework.cglib.proxy.enhancer تنفيذ طريقة وكيل CGLIB * Author Administrator * */public class mycglibitils {/** * إنشاء كائن وكيل باستخدام طريقة cglib * return */public bookdaoimpl getProxy () {endancer ensancer = new ensancer () ؛ // قم بتعيين ensancer.SetSuperClass (BookdaoImpl.Class) ؛ // قم بتعيين محسن دالة رد الاتصال. تم تنفيذه ") ؛} methodproxy.invokesuper (obj ، objs) ؛ // هي الطريقة التي تم تنفيذها}}) ؛ // إنشاء كائن الوكيل bookdaoimpl proxy = (bookdaoimpl) ensancer.create () ؛ عودة الوكيل. }}3) كتابة فصول الاختبار
package com.clj.demo4 ؛ import org.junit.test ؛ public class demo1 {test public void run1 () {// target object bookdaoimpl dao = new bookdaoimpl () ؛ dao.save () ؛ dao.update () ؛ System.out.println ("=================================)3. تطوير AOP الربيعي استنادًا إلى SABNEJ (طريقة ملف التكوين)
1) نشر البيئة واستيراد حزمة الجرة المقابلة
2) إنشاء ملفات التكوين وتقديم قيود AOP
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd ">
3) إنشاء واجهات وتنفيذ الفصول
Package com.clj.demo5 ؛ public interface customerdao {public void save () ؛ تحديث الفراغ العام () ؛} Package com.clj.demo5 ؛/** * استخدم ملف التكوين لتفسير AOP * Author Administrator * */public clustydaoimpl الذي ينفذ CustomerDao {Override public void save () {// simulate stispion // int a = 10/0 ؛ System.out.println ("حفظ العميل") ؛ } Override public void update () {// todo method method method system.out.println ("" تحديث العميل ") ؛ }}4) تحديد فئة الوجه
Package com.clj.demo5 ؛ استيراد org.aspectj.lang.proceedingjoinpoint ؛/** * فئة الوجه: نقطة الإدخال + الإخطار * Author Administrator * */public class myaspectxml {/** * * الإخطار (تحسين محدد) } / ** * يتم تنفيذ الطريقة بنجاح أو سيتم تنفيذ الاستثناءات * / public void بعد () {system.out.println ("الإخطار النهائي") ؛ } /*** بعد تنفيذ الطريقة ، يتم تنفيذ إشعار النشر. في حالة حدوث استثناء في البرنامج ، فلن يتم تنفيذ إشعار النشر */ public void بعد return () {system.out.println ("إشعار ما بعد") ؛ } / ** * بعد تنفيذ الطريقة ، إذا كان هناك استثناء ، فسيتم تنفيذ إشعار الاستثناء * / public void lefthrowing () {system.out.println ("إخطار الاستثناء") ؛ } /*** الإخطار المحيط: يتم الإخطار قبل وبعد تنفيذ الطريقة. * بشكل افتراضي ، لا يمكن تنفيذ طريقة الكائن المستهدف ، ويجب تنفيذ الكائن الهدف يدويًا */ public void حول (proseingJoinPoint Joinpoint) {system.out.println ("الإخطار التفت 1") ؛ // يدويًا ، اترك طريقة الكائن الهدف تنفيذ Try {JoinPoint.proceed () ؛ } catch (throwable e) {// todo acto catch block e.printstacktrace () ؛ } system.out.println ("WRAP Notification 2") ؛ }}5)注入实现类和切面类
<?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: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 --> <!-- 配置客户的dao --> <bean id="customerDao"/> <!-- 编写切面类配置好--> <bean id="myAspectXml"/> <!-- 配置AOP --> <aop:config> <!-- 配置切面类:切入点+通知(类型)--> <aop:aspect ref="myAspectXml"> <!-- 配置前置通知,save方法执行之前,增强方法会执行--> <!-- 切入点表达式:execution(public void com.clj.demo5.CustomerDaoImpl.save()) --> <!-- 切入点表达式: 1.execution()固定的,必写2.public可以省略不写3.返回值必写,严格根据切入点方法而定,否则增强方法不会执行,可以用*代替,表示任意的返回值4.包名必写,可以用*代替(如:*..*(默认所有包); com.clj.*) 5.类名必写,可以部分用*(如*DaoImpl表示以'DaoImpl'结尾的持久层实现类),但不建议用*代替整个类名6.方法必写,可以部分用*(如save*表示以'save'开头的方法),但不建议用*代替整个类名7.方法参数根据实际方法而定,可以用'..'表示有0或者多个参数--> <!-- <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" encoding="UTF-8"?><beans 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.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"> <!-- 配置最终通知<aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置后置通知<aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置异常通知<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" 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" 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"> <!-- 开启自动注解代理--> <aop:aspectj-autoproxy/> <!-- 配置目标对象--> <bean id="customerDao"/> <!-- 配置切面类--> <bean id="myAspectAnno"/></beans>
spring提供了JDBC模板:JdbcTemplate类
1.快速搭建
1)部署环境
这里在原有的jar包基础上,还要添加关乎jdbc的jar包,这里使用的是mysql驱动
2)配置内置连接池,将连接数据库程序交给框架管理,并配置Jdbc模板类
<?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" 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"> <!-- 先配置连接池(内置) --> <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> <!-- 配置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" 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" 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"><!-- 配置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><!-- 配置JDBC的模板类--> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean><!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean><bean id="accountDao"> <!-- 注入模板类--> <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" 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" 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"> <!-- 配置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="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" 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" 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"> <!-- 配置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="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 手动编码方式,提供了模板类,使用该类管理事务比较简单--> <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" 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" 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"> <!-- 配置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> <!-- 申明式事务(采用XML文件的方式) --> <!-- 先配置通知--> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知--> <aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config> <!-- 配置业务层和持久层--> <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" 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" 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"> <!-- 配置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:annotation-driven transaction-manager="transactionManager"/> <!-- 配置业务层和持久层--> <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 أكثر.