Kerangka kerja musim semi dibuat karena kompleksitas pengembangan perangkat lunak. Spring menggunakan Javabeans dasar untuk melakukan hal -hal yang sebelumnya hanya dimungkinkan oleh EJB. Namun, tujuan Spring tidak terbatas pada pengembangan sisi server. Dari perspektif kesederhanaan, testabilitas dan kopling longgar, sebagian besar aplikasi Java dapat memperoleh manfaat dari musim semi. Spring adalah kerangka kontainer inversi kontrol ringan (IOC) dan berorientasi bagian (AOP).
◆ Tujuan: Selesaikan kompleksitas pengembangan aplikasi perusahaan
◆ Fungsi: Gunakan Javabean Dasar bukan EJB, dan menyediakan lebih banyak fungsi aplikasi perusahaan
◆ Lingkup: Aplikasi Java apa pun
Inversi kontrol (IOC dalam singkatan bahasa Inggris) memberikan hak untuk membuat objek ke kerangka kerja, yang merupakan fitur penting dari kerangka kerja dan bukan istilah khusus untuk pemrograman yang berorientasi objek. Ini termasuk injeksi ketergantungan dan pencarian ketergantungan. Di lapisan bisnis tradisional, ketika sumber daya diperlukan, sumber daya baru ditemukan di lapisan bisnis, sehingga kopling (saling ketergantungan dan korelasi antar program) lebih tinggi. Sekarang serahkan bagian baru ke pegas untuk mencapai kohesi tinggi dan kopling rendah. Singkatnya: Awalnya, setiap kali metode lapisan DAO atau lapisan layanan dipanggil, aplikasi akan menggunakan yang baru, dan sekarang hak -hak baru diserahkan ke musim semi, dan sumber daya apa yang dibutuhkan diperoleh dari musim semi!
1. Unduh Paket Jar Ketergantungan yang Diperlukan untuk Kerangka
Situs web Spring resmi adalah: http://spring.io/
Unduh Paket JAR: http://repo.springsource.org/libs-release-local/org/springframework/spring
2. Impor Paket Jar Dasar
Faktanya, stoples inti dasar termasuk kacang; konteks; inti; paket ekspresi, dan yang lainnya bergantung pada log log4J. Tentu saja, stoples musim semi lebih dari itu, mereka ditambahkan perlahan di tahap selanjutnya.
3. Konfigurasikan File Konfigurasi Log4J
File log didefinisikan dalam direktori SRC
### pesan log langsung ke stdout ### log4j.appender.stdout = org.apache.log4j.consoleAppenderLog4j.applender.stdout.target = System.errlog4j.applog.stdout.layout = org.apache.log4j.patternlayoutlog4j.appender.stdout %c {1}: %l - %m %n ### pesan langsung untuk mengajukan mylog.log ### log4j.appender.file = org.apache.log4j.fileAppenderlog4j.applent.file.file = c/: mylog.loglog4j.appender.file.layout = org.apache.log4j.patternlayoutlog4j.applay.file.file %c {1}: %l - %m %n ### Set Level Log - Untuk lebih banyak perubahan logging verbose 'info' menjadi 'debug' ### log4j.rootlogger = info, stdout4. Uji apakah file log berhasil digunakan
Paket com.clj.demo1; import org.apache.log4j.logger; impor org.junit.test;/** * penggunaan log demo * @Author Administrator * */kelas publik demo1 {// Buat log Log Class Private Logger = Logger.getLogger (demo1.class); @Test public void run1 () {// Ubah info di atribut log4j.rootlogger menjadi off, dan log.info ("execute"); }}5. Tentukan antarmuka dan mengimplementasikan kelas
Antarmuka:
Paket com.clj.demo2; antarmuka publik Userservice {public void wayshello ();}Kelas Implementasi
Paket com.clj.demo2; kelas publik UserserviceImpl mengimplementasikan UsersEverService {private string name; public string getName () {return name; } public void setName (name string) {this.name = name; } public void init () {System.out.println ("Inisialisasi .."); } public void sayshello () {System.out.println ("Hello Spring"+"/t"+name); } public void destory () {System.out.println ("Destroy .."); }}6. Tentukan file konfigurasi spesifik pegas
Tentukan nama ApplicationContext.xml, lokasi adalah SRC, direktori yang sama dengan file log, impor kendala yang sesuai, dan suntikkan kelas implementasi ke dalam file konfigurasi. Mulailah dengan awal, gunakan kendala kacang
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: p = "http://www.springframework.org/schema/p" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org.org/schema/beans http://www.spramework.org.org/beans Tag 1. Nilai ID adalah unik (harus menulis) 2. Catatan: Kelas adalah classpath implementasi, bukan antarmuka (harus menulis) 3. Inisialisasi bekerja sebelum metode inti dieksekusi (pilih write) 4. Inisialisasi bekerja setelah metode inti dieksekusi (Pilih Tulis)-<bean id = "name" name "name" name ("name" name- "name" name "name" name "name" name "name" name "name" name "name" name " </tagel> </tobel>7. Tes
Public Class Demo1 { /*** Cara Asli* /@test public void run () {// Buat kelas implementasi UserserViceImpl S = baru UserserViceImpl (); S.SetName ("Jaxiansen"); s.sayhello (); } / *** Versi Pabrik Lama BeanFactory* Pabrik lama tidak akan membuat objek file konfigurasi* / @test public void run2 () {beanfactory factory = new xmlBeanFactory (classpathResource baru ("applicationContext.xml")); UserserService US = (Userservice) factory.getBean ("UserserService"); us.sayhello (); } /** * Use spring framework IOC method* Create a startup server in the new version of factory to create a configuration file object, and there is no need to load the factory when calling again*/ @Test public void run3(){ //Create the factory and load the core configuration file (ClassPathXmlApplicationContext is found under src) ApplicationContext ac=new ClasspathxmlapplicationContext ("applicationContext.xml"); // Dapatkan objek dari pabrik (nilai ID dalam file konfigurasi, polimorfisme digunakan di sini) UserService USI = (Userservice) ac.getBean ("UserserService"); // Memanggil metode objek untuk mengeksekusi USI.SayHello (); } /** * Demo destroy-method method* The bean destroy method will not be automatically executed* Unless it is automatically called in scope= singleton or in a web container, the main function or test case needs to be called manually (need to use the close() method of ClassPathXmlApplicationContext) */ @Test public void run4(){ //Create a factory and load the core configuration file (ClassPathXMLapPLicationContext ditemukan di bawah SRC) ClassPathXMLapPLicationContext ac = new ClassPathXMLapPlicationContext ("ApplicationContext.xml"); // Dapatkan objek dari pabrik (nilai ID dalam file konfigurasi, polimorfisme digunakan di sini) UserService USI = (Userservice) ac.getBean ("UserserService"); // Memanggil metode objek untuk mengeksekusi USI.SayHello (); // ApplicationContext Implementasi Kelas menyediakan metode yang dekat, dan pabrik dapat ditutup dan metode-metode destori dapat dieksekusi. }}Perbedaan antara pabrik lama dan pabrik baru
* Perbedaan antara BeanFactory dan ApplicationContext
* Beanfactory - beanfactory membutuhkan pemuatan malas, dan kacang akan diinisialisasi hanya saat Anda mendapatkan pertama kali
* ApplicationContext - Saat memuat ApplicationContext.xml, contoh spesifik dari objek bean akan dibuat, dan beberapa fungsi lain disediakan.
* Pengiriman Acara
* Unit Otomatis Bean
* Implementasi konteks dari berbagai lapisan aplikasi
Ringkasan: Ini adalah demo paling dasar, yang mengonfigurasi kelas implementasi ke dalam file konfigurasi pegas. Setiap kali server dimulai, file konfigurasi akan dimuat, dengan demikian instantiasi kelas implementasi.
1. Apa itu injeksi ketergantungan?
Musim semi dapat secara efektif mengatur objek tingkat aplikasi J2EE. Apakah itu objek tindakan dari lapisan kontrol, objek layanan dari lapisan bisnis, atau objek DAO dari lapisan kegigihan, itu dapat dikoordinasikan secara organik dan dijalankan di bawah manajemen musim semi. Spring mengatur objek dari setiap lapisan bersama -sama dengan cara yang digabungkan secara longgar. Objek tindakan tidak perlu peduli dengan implementasi spesifik objek layanan, objek layanan tidak perlu peduli dengan implementasi spesifik objek lapisan persisten, dan panggilan ke setiap objek layer sepenuhnya berorientasi antarmuka. Ketika sistem perlu di -refactored, jumlah penulisan ulang kode akan sangat berkurang. Injeksi ketergantungan membuat kacang dan kacang terorganisir dalam file konfigurasi, daripada hardcoded. Memahami suntikan ketergantungan
Injeksi ketergantungan dan inversi kontrol adalah konsep yang sama. Arti spesifiknya adalah: ketika peran (mungkin contoh Java, penelepon) membutuhkan bantuan dari peran lain (instance Java lain, penelepon), dalam proses pemrograman tradisional, penelepon biasanya dibuat oleh penelepon. Tetapi di musim semi, pekerjaan menciptakan callee tidak lagi dilakukan oleh penelepon, jadi itu disebut inversi kontrol; Pekerjaan membuat instance callee biasanya dilakukan oleh wadah pegas dan kemudian disuntikkan ke penelepon, sehingga juga disebut injeksi ketergantungan.
Apakah itu injeksi ketergantungan atau inversi kontrol, itu berarti bahwa Spring mengadopsi cara yang dinamis dan fleksibel untuk mengelola berbagai objek. Implementasi spesifik antara objek saling transparan.
2. Konsep IOC dan DI
* IOC - Kebalikan dari kontrol, inversi kontrol, membalikkan hak penciptaan objek ke Spring! Lai
* DI - Injeksi ketergantungan, injeksi ketergantungan, ketika kerangka kerja pegas bertanggung jawab untuk membuat objek kacang, secara dinamis menyuntikkan objek ketergantungan ke dalam komponen kacang! Lai
3. Demo
Untuk variabel anggota kelas, ada dua metode injeksi umum.
Injeksi Metode Set Properti dan Metode Konstruktor Injeksi
Pertama menunjukkan tipe pertama: injeksi metode set properti
1) Lapisan persisten
Paket com.clj.demo3; kelas publik customerdaoImpl {public void save () {System.out.println ("I Am Dao dari Kegistence Layer"); }}2) Lapisan Bisnis
CATATAN: Pada saat ini, saya ingin menyuntikkan lapisan kegigihan ke lapisan bisnis dan menyerahkan hak untuk membuat contoh lapisan persistensi ke kerangka kerja, syaratnya adalah bahwa lapisan bisnis harus memberikan atribut anggota dan menetapkan metode dari lapisan persistensi.
Paket com.clj.demo3;/** * Injeksi ketergantungan menyuntikkan lapisan DAO ke lapisan layanan * @Author Administrator * */Public Class CustomerServiceImpl {// Berikan anggota Zodiac, berikan metode yang ditetapkan Pelanggan Pelanggan Privat Pelanggan Pelanggan Pribadi; public void setCustomerdao (customerdaoImpl customerdao) {this.customerdao = customerdao; } public void save () {System.out.println ("I Am The Service ..."); // 1. Metode asli // customerdaoImpl baru (). Save (); //2.spring metode IOC customerdao.save (); }}3) Konfigurasi Konfigurasi File
<!-Injeksi ketergantungan demonstrasi-> <bean id = "customerdao"/> <bean id = "customerservice"> <!-menyuntikkan dao ke lapisan layanan-> <nama properti = "customerdao" ref = "customerdao"> </properti> </tact>
4) Tes
/** * Metode Injeksi Ketergantungan Musim Semi * menyuntikkan lapisan DAO ke lapisan layanan */@test public void run2 () {// Buat pabrik, muat file konfigurasi, dan layanan pelanggan dibuat, sehingga membuat customerdao applicationContext context = new ClassPathxMlicationContext ("ApplicationContext.xml"); CustomerServiceImpl cSI = (customerserviceImpl) context.getBean ("customerservice"); csi.save (); }Tipe Kedua: Injeksi Metode Konstruksi
1) Pojo Class dan berikan metode konstruktor
Paket com.clj.demo4;/** * Metode injeksi demo * @author administrator * */kelas publik car1 {private string cName; harga ganda pribadi; car1 publik (string cName, harga ganda) {super (); this.cname = cName; this.price = harga; } @Override Public String ToString () {return "car1 [cname =" + cname + ", price =" + price + "]"; }}2) Konfigurasi Konfigurasi File
<!-Demonstrasi metode injeksi metode konstruksi-> <bean id = "car1"> <!-tulis metode 1 <konstruktor-arg name = "cname" value = "bmw"/> <konstruktor-arg name = "harga" value = "400000"/> <!-Metode Tulis 2-> <Konstruktor-Arg Nilai = "0" 0 "Nilai" 0 " value = "400000"/> </bean>
3) Tes
@Test public void run1 () {applicationContext ac = new classpathxmlappleCicationContext ("applicationContext.xml"); Car1 car = (car1) ac.getbean ("car1"); System.out.println (mobil); }Ekstensi: Membangun Metode menyuntikkan satu objek ke yang lain
1) Pojo Class: Tujuan: Menyuntikkan mobil di kolom di atas ke manusia dan menjadikannya salah satu atribut. Di kelas ini, atribut anggota mobil harus disediakan dan metode konstruksi yang diparameterisasi harus disediakan.
paket com.clj.demo4; orang kelas publik {name string pribadi; Private Car1 Car1; orang publik (nama string, car1 car1) {super (); this.name = name; this.car1 = car1; } @Override public string toString () {return "person [name =" + name + ", car1 =" + car1 + "]"; }}2) File Konfigurasi
<!-Name Konstruktor-Arg = "Name" Value = "Jaxiansen"/> <konstruktor-arg name = "car1" ref = "car1"/> </bean>
4. Cara menyuntikkan array koleksi
1) Tentukan kelas pojo
Paket com.clj.demo4; import java.util.arrays; import java.util.list; import java.util.map; Daftar Pribadi <String> Daftar; set private <string> set; peta pribadi <string, string> peta; Private Properties Pro; public void setPro (Properties Pro) {this.pro = pro; } public void setSets (set <string> sets) {this.sets = set; } public void setMap (peta <string, string> peta) {this.map = peta; } public void setList (Daftar <String> daftar) {this.list = daftar; } public void setArrrs (string [] arrrs) {this.arrs = arrrs; } @Override Public String ToString () {return "user [arrs =" + arrays.toString (arrs) + ", list =" + list + ", set =" + set + ", peta =" + peta + ", pro =" + pro + "]"; }}2) File Konfigurasi
<!-Set Injeksi-> <bean id = "user"> <!-array-> <name properti = "arrs"> <cist> <value> number1 </value> <value> number2 </value> <value> number3 </value> </list> </list> <!-set daftar-> <nama properti = "Daftar"> <ter list> </list> <propert> </property> <!-Set Set-> <Properti Nama = "Set"> <set> <value> haha </value> <value> haha </value> </ set> </propert> <!-set peta-> <name properti = "peta"> <MAP> <entri key = "aa" value = "rainbow"/<entry tey = "bb" value =! name = "Pro"> <props> <prop key = "username"> root </prop> <prop key = "password"> 123 </prop> </props> </prop Property> </bean>
3) Tes
/ *** Koleksi Injeksi Tes*/ @test public void run3 () {ApplicationContext ac = new ClassPathXMLapPlicationContext ("ApplicationContext.xml"); Pengguna pengguna = (pengguna) ac.getBean ("pengguna"); System.out.println (pengguna); }5. Cara Mengembangkan dalam Modul
Tambahkan tag <impor> ke file konfigurasi utama (asumsikan bahwa, file konfigurasi applicationContext2.xml didefinisikan di bawah paket com.clj.test)
<!-Memperkenalkan file konfigurasi lain dengan pengembangan modul-> <impor sumber daya = "com/clj/test/applicationContext2.xml"/>
1. Memulai
1). Paket Jar Import
Selain 6 paket sebelumnya, Anda juga memerlukan paket Spring-AOP untuk bermain anotasi.
2). Lapisan Persistensi dan Lapisan Implementasi (antarmuka diabaikan di sini)
Lapisan persisten
Paket com.clj.demo1; impor org.springframework.context.annotation.scope; impor org.springframework.stereotype.sponent; impor org.springframework.stereotype.repository; Userdao {@Override public void save () {System.out.println ("Simpan klien .."); }}Lapisan bisnis
Paket com.clj.demo1; impor javax.annotation.postconstruct; impor org.springframework.beans.factory.annotation.Autowired; impor org.springframework.beans.factory.annotation.qalifier; impor org.spramework.beanfacpory org.springframework.stereotype.component; Public Class UserserviceImpl mengimplementasikan UsersEverService {@Override public void wayshello () {System.out.println ("Hello Spring"); }}3). Tentukan file konfigurasi
Saat ini, kendala perlu menambahkan kendala konteks dan menambahkan pemindaian komponen
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: context = "http://www.springframework.org/schema/context" xsi: schemalocation = "http://www.springframework.org/schema/beans http:/wwww.springframework http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-Definisi Bean di sini-> <!-Open Annotation Scan: Base-Takik" Definisi Bean di sini-> <! Base-package = "com.clj.demo1"/> </tobel>
4) Tambahkan anotasi ke kelas implementasi
/*** Anotasi Komponen, yang dapat digunakan untuk menandai kelas saat ini* Mirip dengan <bean id = "Userservice">* Nilai berarti memberikan alias untuk kelas*/@komponen (value = "Userservice") Public Class UserServiceImpl mengimplementasikan Userservice {// dihilangkan}5) Menulis tes
/ *** Metode anotasi*/ @test public void run2 () {applicationContext ac = new classpathxmlapplicationContext ("applicationContext.xml"); UserserService US = (UserserService) ac.getBean ("UserserService"); us.sayhello (); }2. Tentang Atribut Umum Manajemen Kacang
1. @Component: Komponen. (bertindak di kelas) Anotasi paling primitif, tidak apa -apa untuk menulis ini untuk semua kelas yang membutuhkan anotasi, itu umum
2. Tiga anotasi turunan @Component disediakan di musim semi: (fungsinya saat ini konsisten)
* @Controller - Bekerja di lapisan web
* @Service - bertindak di tingkat bisnis
* @Repository - bertindak pada lapisan kegigihan
* Catatan: Ketiga anotasi ini dimaksudkan untuk membuat tujuan kelas anotasi itu sendiri jelas, dan musim semi akan meningkatkannya dalam versi berikutnya.
3. Anotasi untuk injeksi atribut (Catatan: Saat menggunakan injeksi anotasi, Anda tidak perlu memberikan metode yang ditetapkan)
* Jika itu adalah jenis injeksi yang normal, Anda dapat menggunakan anotasi nilai
* @Value - untuk menyuntikkan tipe normal
* Jika jenis objek yang disuntikkan, gunakan anotasi berikut
* @Autowired - Secara default, jenisnya secara otomatis dirakit berdasarkan jenis, dan tidak ada hubungannya dengan nama kelas dari kelas yang disuntikkan.
* Jika Anda ingin menyuntikkan dengan nama
* @Qualifier - Penggunaan injeksi nama yang dipaksakan harus digunakan dengan autowired, tentukan nama kelas, dan terkait dengan nama kelas yang disuntikkan
* @Resource - setara dengan @Autowired dan @qualifier
* Tekankan: Anotasi yang disediakan oleh Java
* Atribut menggunakan atribut nama
4. Anotasi lingkup kacang
* Dianotasi sebagai @scope (value = "prototipe"), yang digunakan pada kelas. Nilai -nilainya adalah sebagai berikut:
* singleton - singleton, nilai default
* prototipe - beberapa kasus
5. Konfigurasi siklus hidup kacang (mengerti)
* Anotasi adalah sebagai berikut:
* @PostConstruct-setara dengan init-Method
* @Predestroy-setara dengan metode menghancurkan
1. Demonstrasi anotasi objek atribut
Kondisi: Suntikan atribut (nama) dan objek (userdaoImpl) ke dalam lapisan bisnis dengan memindai.
1) Buka lapisan kegigihan untuk memindai anotasi
//@component (value = "userdao") universal class annotation@repository (value = "ud") kelas publik userdaoImpl mengimplementasikan userdao {@Override public void save () {System.out.println ("Simpan Klien .."); }}2) Lapisan bisnis memberikan anotasi untuk atribut dan objek
Paket com.clj.demo1; impor javax.annotation.postconstruct; impor org.springframework.beans.factory.annotation.Autowired; impor org.springframework.beans.factory.annotation.qalifier; impor org.spramework.beanfacpory org.springframework.stereotype.Component;/** * Component annotation, can be used to mark the current class* Similar to <bean id="userService"> * value means giving an alias to the class *///@Scope(value="grototype") multiple columns (singletype is a single column) @Component(value="userService") public class UserServiceImpl implements UserService{ // Atribut Anotasi: Ini setara dengan menyuntikkan string yang ditentukan ke atribut nama. Metode SetName dapat dihilangkan tanpa menulis @Value (value = "jaxiansen") nama string pribadi; /** * Reference injection method 1: Autowired() * Reference injection method 2: Autowired() + Qualifier * Reference injection method 3: @Resource(name="userDao") java method, identify injection by name*/ //Autowired() is automatically assembled and injected by type (disadvantages: because it matches by type, so it is not very accurate) @Autowired() @Qualifier (value = "ud") // injeksi dengan nama, itu harus digunakan dengan autowired. Keduanya dapat menentukan kelas Userdao Ususdao Private; // Perhatikan bahwa nilai dalam kualifikasi adalah nama anotasi di bagian atas nama kelas UserdaoImpl, atau Anda dapat menentukan nama ID kacang dalam file konfigurasi/*public void setName (nama string) {this.name = name; }*/ @Override public void wayshello () {System.out.println ("Hello Spring"+Name); userdao.save (); } // @postconstruct tag anotasi untuk inisialisasi dalam aksi lifecycle @postconstruct public void init () {System.out.println ("Inisialisasi ..."); }}3) File konfigurasi hanya perlu diaktifkan untuk memindai semua file konfigurasi
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: context = "http://www.springframework.org/schema/context" xsi: schemalocation = "http://www.springframework.org/schema/beans http:/wwww.springframework http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-Definisi Bean di sini-> <!-Open Annotation Scan: Base-Takik" Definisi Bean di sini-> <! Base-package = "com.clj.demo1"/> </tobel>
Catatan: Sedangkan untuk koleksi, disarankan untuk menggunakan file konfigurasi
2. Kerangka kerja musim semi mengintegrasikan pengujian unit junit
1) Tambahkan paket ketergantungan yang diperlukan spring-test.jar
Catatan: Myeclipes hadir dengan lingkungan JUnit sendiri, tetapi kadang -kadang karena masalah versi, lingkungan JUnit baru mungkin diperlukan. Di sini saya telah mengunduh paket JAR JUnit-4.9 baru secara online. Jika myeclipes lebih baru, Anda tidak perlu mempertimbangkannya.
2) Tulis kelas tes dan tambahkan anotasi yang sesuai
@Runwith dan @contextConfiguration (ini digunakan untuk memuat file konfigurasi, karena jalur default dari Webroot adalah direktori tingkat pertama, ditambah ini untuk menentukan bahwa SRC adalah direktori tingkat pertama)
Paket com.clj.demo2; impor javax.annotation.resource; impor org.junit.test; impor org.junit.runner.runwith; impor org.springframework.test.context.contextConfiguration; impor org.springframework.test.context.contextconfiguration; Impor org.springframework.test.context.contextConfiguration; com.clj.demo1.userservice; @runwith (springjunit4classrunner.class) @contextConfiguration ("classpath: applicationContext.xml") kelas publik Demo2 {@Resource (name = "Userservice") UserserService UserService; @Test public void run1 () {UserserVice.sayhello (); }}6. AOP Kerangka Musim Semi
1. Apa itu AOP
* Dalam industri perangkat lunak, AOP adalah singkatan dari pemrograman berorientasi aspek, Arti: Pemrograman Facet, Modularitas Fungsional
* AOP adalah paradigma pemrograman, berafiliasi dengan kategori kerja lunak, membimbing pengembang cara mengatur struktur program
* AOP pertama kali diusulkan oleh organisasi AOP Alliance dan merumuskan serangkaian norma. Spring memperkenalkan ide -ide AOP ke dalam kerangka kerja dan harus mematuhi spesifikasi AOP Alliance.
* Teknologi untuk mencapai pemeliharaan fungsi program terpadu melalui prekompilasi dan agen dinamis selama runtime
* AOP adalah kelanjutan dari OOP, topik hangat dalam pengembangan perangkat lunak, bagian penting dari kerangka kerja Spring, dan paradigma turunan dari pemrograman fungsional.
* Menggunakan AOP, berbagai bagian logika bisnis dapat diisolasi, sehingga mengurangi kopling antara bagian -bagian logika bisnis, meningkatkan penggunaan kembali program, dan meningkatkan efisiensi pengembangan.
AOP mengadopsi mekanisme ekstraksi horizontal, mengganti kode berulang dari sistem warisan vertikal tradisional (pemantauan kinerja, manajemen transaksi, inspeksi keamanan, caching)
2. Mengapa belajar aop
* Program dapat ditingkatkan tanpa memodifikasi kode sumber! Lai (Buat proxy untuk metode yang tetap. Sebelum mengakses metode, masukkan proxy terlebih dahulu. Di proxy, Anda dapat menulis lebih banyak fungsi untuk membuat metode lebih kuat dan meningkatkan program)
AOP: Pemrograman berorientasi, memodulasi segalanya, setiap modul relatif independen, modul dapat dibagikan (sama), dan berbeda khususnya disesuaikan. Gunakan ini alih -alih pemrograman vertikal tradisional untuk meningkatkan penggunaan kembali program
3. Implementasi AOP (Prinsip Implementasi)
Implementasi AOP mencakup dua metode proxy <1> untuk mengimplementasikan antarmuka kelas: Gunakan proxy dinamis JDK <2> tidak diimplementasikan antarmuka kelas: Gunakan proxy dinamis CGLIB
1. Menerapkan proxy dinamis JDK
1) Tentukan kelas implementasi antarmuka lapisan persistensi
paket com.clj.demo3; antarmuka publik userdao {public void save (); pembaruan public void ();} paket com.clj.demo3; kelas publik userdaoImpl mengimplementasikan userdao {@Override public void save () {System.out.println ("Simpan Pengguna"); } @Override public void update () {System.out.println ("Modifikasi Pengguna"); }}2) Tentukan kelas alat proxy dinamis JDK
Kelas alat ini menambahkan beberapa fungsi saat mengeksekusi metode penyelamatan lapisan persistensi, dan dalam pengembangan, perlu untuk meningkatkan metode tanpa mengubah kode sumber.
Paket com.clj.demo3; impor java.lang.reflect.invocationHandler; import java.lang.reflect.method; import java.lang.reflect.proxy;/** * Hasilkan objek proxy di jdk (prinsip AOP) * @Aratic Publicy * Publicy * Publicy Publicy * getProxy (Userdao Dao akhir) {// Gunakan kelas proxy untuk menghasilkan objek proxy userdao proxy = (userdao) proxy.newproxyinstance (dao.getClass (). dieksekusi setelah objek publik Invoke (Proxy Object, Metode Metode, Object [] args) Melemparkan Throwable {// Proxy mewakili objek proxy saat ini // metode metode yang dieksekusi oleh objek saat ini // args yang dienkapsulasi parameter // Biarkan kelas atau perbarui Metode Eksekusi secara normal jika ("save" .Equals (Method.getName ())) {()) {{execute. " return method.invoke (dao, args);}}); Return proxy; }}3) Tes
Paket com.clj.demo3; impor org.junit.test; kelas publik demo1 {@test public void run1 () {// Dapatkan objek target userdao dao = UserdaoImpl baru (); dao.save (); dao.update (); System.out.println ("===================================================================================== ============================================================================================================ Gunakan kelas alat untuk mendapatkan proxy proxy userdao proxy = myproxyutils.getproxy (DAO);2. Menerapkan Teknologi CGLIB
1) Tentukan lapisan kegigihan, tidak ada antarmuka saat ini
Paket com.clj.demo4; kelas publik bookdaoImpl {public void save () {System.out.println ("Simpan Buku"); } public void update () {System.out.println ("Modify Book"); }}2) Tulis kelas alat
Paket com.clj.demo4; impor java.lang.reflect.method; impor org.springframework.cglib.proxy.enhancer; prinsip org.springframework.cglib.proxy.methodinteptor; impor org.springframpewework.cglib.proxy. Metode Proxy * Administrator @Author * */Kelas Publik MyCGlibutils {/** * Menghasilkan objek proxy menggunakan metode CGLIB * @return */public static bookdaoImpl getProxy () {penambah penambah = penambah baru (); // Atur penambah kelas induk. // Atur penambah fungsi callback.setCallback (MethodInterceptor baru () {@Override Public Object Intercept (objek OBJ, metode metode, objek [] objs, methodproxy methodproxy) melempar Throwable {if (Method.getname (). Equals ("save")) {System.out.println ("i saveD (). Equals (" save ") {System.out.println (" i SaveD ("). } return methodproxy.invokeSuper (obj, objs); // adalah metode yang dieksekusi}}); // Hasilkan proxy objek bookdaoImpl proxy = (bookdaoImpl) Enhancer.create (); Return proxy; }}3) Tulis kelas tes
paket com.clj.demo4; impor org.junit.test; kelas publik demo1 {@test public void run1 () {// target objek bookdaoImpl dao = bookdaoImpl baru (); dao.save (); dao.update (); System.out.println ("===============================); bookdaoImpl proxy = mycglibutils.getproxy (); proxy.save (); proxy.update ();}};3. Pengembangan AOP Spring Berdasarkan Aspekj (Metode File Konfigurasi)
1) Menyebarkan lingkungan dan mengimpor paket JAR yang sesuai
2) Buat file konfigurasi dan perkenalkan kendala AOP
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http:/xmlschema" xmlns: aop = "http:pfor XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop http:/www.spramework.org/schaMaMema http://www.springframework.org/schema/aop/spring-aop.xsd ">
3) Buat antarmuka dan mengimplementasikan kelas
paket com.clj.demo5; antarmuka publik customerdao {public void save (); pembaruan public void ();} Paket com.clj.demo5;/** * Gunakan file konfigurasi untuk menginterpretasikan AOP * @Author Administrator * */kelas publik CustomerdaoImpl mengimplementasikan customerdao {@Override public void save () {// Simulasikan pengecualian // int a = 10/0; System.out.println ("Simpan Pelanggan"); } @Override public void update () {// TODO METODE AUTO-EKSIREATED Stub System.out.println ("Diperbarui Pelanggan"); }}4) Tentukan kelas facet
Paket com.clj.demo5; impor org.aspectj.lang.proedingjointPoint;/** * kelas facet: titik masuk + pemberitahuan * @author administrator * */kelas publik myaspectxml {/** * pemberitahuan (peningkatan spesifik) */public void log () {System.out.println (" } / ** * Metode ini dijalankan dengan sukses atau pengecualian akan dieksekusi * / public void setelah () {System.out.println ("Pemberitahuan Akhir"); } /*** Setelah metode dieksekusi, pemberitahuan posting dijalankan. Jika pengecualian terjadi dalam program, pemberitahuan pos tidak akan dieksekusi */ public void afterReturn () {System.out.println ("Posting pemberitahuan"); } / ** * Setelah metode dieksekusi, jika ada pengecualian, pemberitahuan pengecualian akan dieksekusi * / public void afterthrowing () {System.out.println ("Pemberitahuan Pengecualian"); } /*** Pemberitahuan surround: Pemberitahuan dibuat sebelum dan sesudah metode dieksekusi. * Secara default, metode objek target tidak dapat dieksekusi, dan objek target perlu dieksekusi secara manual */ public void di sekitar (ProsidingJoINPoint gabungan) {System.out.println ("Wrap Notification 1"); // Biarkan metode objek target secara manual mengeksekusi coba {joinpoint.proed (); } catch (Throwable e) {// TODO Auto-Guiled Catch Block E.PrintStackTrace (); } System.out.println ("Wrap Notification 2"); }}5) menyuntikkan kelas implementasi dan kelas segi
<?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) Tes
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 kelas. 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! Lai
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>
Semua kode
<?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 kelas. 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"/>
Semua kode
<?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 kelas. 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); }}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.