1. Pendahuluan
Dalam proyek -proyek sebelumnya, saya jarang memperhatikan implementasi spesifik dan teori AOP Spring. Saya baru saja mengerti apa itu AOP dan bagaimana menggunakannya. Saya melihat posting blog yang ditulis dengan baik, jadi saya datang untuk mempelajarinya.
AOP
AOP (pemrograman berorientasi aspek), yaitu, pemrograman berorientasi aspek, dapat dikatakan sebagai suplemen dan peningkatan OOP (pemrograman berorientasi objek). OOP memperkenalkan konsep -konsep seperti enkapsulasi, warisan, dan polimorfisme untuk membangun hierarki objek yang digunakan untuk mensimulasikan kumpulan perilaku publik. Namun, OOP memungkinkan pengembang untuk mendefinisikan hubungan vertikal, tetapi tidak cocok untuk mendefinisikan hubungan horizontal, seperti fungsi logging. Kode log sering tersebar secara horizontal di semua tingkat objek, dan tidak ada hubungannya dengan fungsi inti dari objek yang sesuai. Jenis kode yang tidak terkait yang tersebar di mana -mana disebut pemotongan silang. Dalam desain OOP, ini menyebabkan sejumlah besar duplikasi kode, yang tidak kondusif untuk penggunaan kembali setiap modul.
Teknologi AOP, sebaliknya, menggunakan teknik yang disebut "crosscutting" untuk membedah bagian dalam objek yang dienkapsulasi dan merangkum perilaku umum yang mempengaruhi banyak kelas menjadi modul yang dapat digunakan kembali dan menamainya "aspek", yang merupakan faset. "Bagian" yang disebut hanya dienkapsulasi oleh logika atau tanggung jawab yang tidak terkait dengan bisnis tetapi disebut bersama oleh modul bisnis, yang nyaman untuk mengurangi kode duplikat sistem, mengurangi kopling antara modul, dan kondusif untuk operabilitas dan pemeliharaan di masa depan.
Menggunakan teknologi "crosscutting", AOP membagi sistem perangkat lunak menjadi dua bagian: perhatian inti dan kepedulian silang. Proses utama pemrosesan bisnis adalah fokus inti, dan bagian yang tidak ada hubungannya dengan itu adalah fokus cross-sectional. Salah satu fitur dari masalah lintas sekelompok adalah bahwa mereka sering terjadi dalam berbagai masalah inti, dan pada dasarnya serupa di berbagai tempat, seperti otentikasi izin, log, dan hal-hal. Peran AOP adalah untuk memisahkan berbagai kekhawatiran dalam sistem dan memisahkan kekhawatiran inti dari kekhawatiran silang.
Konsep inti AOP
1. Poin perhatian silang
Metode mana yang mencegat dan bagaimana menghadapinya setelah intersepsi? Kekhawatiran ini disebut masalah silang
2. Bagian (aspek)
Kelas adalah abstraksi fitur objek, dan bagian adalah abstraksi dari masalah lintas sektoral
3. Bantalan
Titik yang dicegat, karena pegas hanya mendukung titik koneksi tipe metode, sehingga titik koneksi pada musim semi mengacu pada metode yang dicegat. Bahkan, titik koneksi juga bisa berupa bidang atau konstruktor.
4. Pointcut
Definisi mencegat titik koneksi
5. Pemberitahuan (Saran)
Notifikasi yang disebut mengacu pada kode yang akan dieksekusi setelah mencegat titik koneksi. Pemberitahuan dibagi menjadi lima kategori: pemberitahuan yang sudah ditentukan sebelumnya, post-set, pengecualian, final, dan sekitarnya.
6. Objek target
Objek target proxy
7. Tenun
Proses menerapkan celah ke objek target dan menyebabkan pembuatan objek proxy
8. Pendahuluan
Tanpa memodifikasi kode, pengantar dapat secara dinamis menambahkan beberapa metode atau bidang ke kelas selama periode runtime
Dukungan Musim Semi untuk AOP
Agen AOP di musim semi bertanggung jawab atas pembuatan dan pengelolaan wadah IOC musim semi, dan ketergantungannya juga dikelola oleh wadah IOC. Oleh karena itu, proxy AOP dapat secara langsung menargetkan instance kacang lainnya dalam wadah, dan hubungan ini dapat disediakan dengan injeksi ketergantungan wadah IOC. Aturan untuk membuat proxy di musim semi adalah:
1. Secara default, Java Dynamic Proxy digunakan untuk membuat proxy AOP, sehingga Anda dapat membuat proxy untuk setiap instance antarmuka apa pun.
2. Ketika kelas yang membutuhkan proxy bukan antarmuka proxy, pegas akan beralih ke penggunaan proxy CGLIB, dan juga dapat memaksa CGLIB untuk digunakan.
Pemrograman AOP sebenarnya adalah hal yang sangat sederhana. Melihat pemrograman AOP, pemrogram hanya perlu berpartisipasi dalam tiga bagian:
1. Tentukan komponen bisnis biasa
2. Tentukan titik masuk, satu titik masuk dapat melintasi beberapa komponen bisnis
3. Tentukan pemrosesan yang ditingkatkan. Peningkatan pemrosesan adalah tindakan pemrosesan yang ditenun menjadi komponen bisnis biasa dalam kerangka AOP.
Oleh karena itu, kunci untuk pemrograman AOP adalah mendefinisikan titik masuk dan mendefinisikan pemrosesan peningkatan. Setelah titik masuk yang sesuai dan pemrosesan peningkatan didefinisikan, kerangka kerja AOP akan secara otomatis menghasilkan proxy AOP, yaitu, metode proxy objek = pemrosesan peningkatan + metode objek proxy.
Berikut ini adalah templat file .xml pegas AOP bernama aop.xml, dan konten selanjutnya diperluas pada aop.xml:
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http:/schema http://www.springframework.org/schema/beans/spring-weans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> </tobel>
Implementasi AOP yang sederhana berdasarkan musim semi
Perhatikan bahwa sebelum menjelaskan, izinkan saya menjelaskan: untuk berhasil menjalankan kode, tidak cukup untuk menggunakan paket JAR yang disediakan oleh Spring kepada pengembang. Silakan unduh dua paket toples secara online:
1. Aopalliance.jar
2. AspectJweaver.jar
Mari kita mulai menjelaskan metode implementasi XML dari pegas AOP, pertama -tama tentukan antarmuka:
antarmuka publik HelloWorld {void printhelloworld (); void doprint ();} Tentukan dua kelas implementasi antarmuka:
kelas publik HelloWorldImpl1 mengimplementasikan HelloWorld {public void printhelloworld () {System.out.println ("Masukkan HelloWorldImpl1.printhelloworld ()"); } public void doprint () {System.out.println ("Enter HelloWorldImpl1.doprint ()"); kembali ; }} kelas publik HelloWorldImpl2 mengimplementasikan HelloWorld {public void printhelloworld () {System.out.println ("Masukkan HelloWorldImpl2.printhelloworld ()"); } public void doprint () {System.out.println ("Masukkan helloWorldImpl2.doprint ()"); kembali ; }} Fokus silang, berikut adalah waktu pencetakan:
TimeHandler kelas publik {public void printTime () {System.out.println ("CurrentTime =" + System.CurrentTimeMillis ()); }} Dengan tiga kelas ini, Anda dapat menerapkan AOP musim semi sederhana. Lihatlah konfigurasi aop.xml:
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http:/schema http://www.springframework.org/schema/beans/spring-weans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <bean id="helloWorldImpl1" /> <bean id="helloWorldImpl2" /> <bean id="timeHandler" /> <aop:config> <aop:aspect id="time" ref="timeHandler"> <aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" /> <aop:before method="printTime" pointcut-ref="addAllMethod" /> <aop:after method="printTime" pointcut-ref="addAllMethod" /> </aop:aspect> </aop:config></beans>
Tulis fungsi utama untuk menyebutnya:
public static void main (string [] args) {applicationContext ctx = new classpathxmlapplicationContext ("aop.xml"); HelloWorld hw1 = (HelloWorld) ctx.getBean ("HelloWorldImpl1"); HelloWorld hw2 = (HelloWorld) ctx.getBean ("HelloWorldImpl2"); hw1.printhellorld (); System.out.println (); hw1.doprint (); System.out.println (); System.out.println (); hw2.printhellorld (); System.out.println (); hw2.doprint ();} Hasil berjalan adalah:
CurrentTime = 1446129611993Enter HelloWorldImpl1.printhellorld () saat ini = 1446129611993CurrentTime = 1446129611994 enterer HelloWorldImpl1.doprint () saat ini = 1446129611194.doprint = 144611111111111111119999999999999 HelloWorldImpl2.printhellorld () CurrentTime = 1446129611994CurrentTime = 1446129611994Enter HelloWorldImpl2.doprint () saat ini = 1446129611994
Saya melihat bahwa semua metode dari dua kelas implementasi antarmuka HelloWorld telah ditambahkan ke proxy, dan konten proxy adalah waktu pencetakan.
Detail tambahan tentang penggunaan AOP berbasis musim semi
1. Tambahkan kekhawatiran silang dan cetak log. Kelas Java adalah:
kelas publik LogHandler {public void logBefore () {System.out.println ("Log sebelum metode"); } public void logafter () {System.out.println ("Log After Method"); }}<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http:/schema http://www.springframework.org/schema/beans/spring-weans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <bean id="helloWorldImpl1" /> <bean id="helloWorldImpl2" /> <bean id="timeHandler" /> <bean id="logHandler" /> <aop:config> <aop:aspect id="time" ref="timeHandler" order="1"> <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.*(..))" /> <aop:before method="printTime" pointcut-ref="addTime" /> <aop:after method="printTime" pointcut-ref="addTime" /> </aop:aspect> <aop:aspect id="log" Ref = "LogHandler" order = "2"> <aop: pointcut id = "printlog" ekspresi = "eksekusi (* com.xrq.aop.hellorld.* (..))" /> <aop: sebelum metode = "Logbefore" pointcut-ref = "printlog" /<aop: after "pointcut" pointcut = "printlog" /<aop: after "after logbefore" pointcut = "point loGaFer =" point logbefore "point" point "point logbefore" </aop: config> </boy>
Kelas tes tetap tidak berubah, dan hasil cetaknya adalah:
CurrentTime = 1446130273734Log sebelum Methodenter HelloWorldImpl1.printhelloworld () log setelah MethodCurrentTime = 1446130273735CurrentTime = 14461302736LOG sebelum Methodenter HelloWorldImpl1.doprint () Methodcurrfcurren = MethodEnTIMETLICEIMLIMPL1.DOPRINT () MODODCURCURTER () SETELAH METODOURCURCERERTER = MODODEWORDIMPL1.DOPRIN () 1446130273736log sebelum methodenter helloWorldImpl2.printhellorld () log setelah methodCurrentTime = 1446130273736CurrentTime = 14461302737log sebelum Methodenter HelloWorldImpl2.doprint () Log Setelah MethodSurenter = 14463.doprint () setelah MethodSurrent = 144613.doprint () setelah MethodCurrent = 144613.doprint () setelah MethodSurentTime = 144613.doprint () setelah MethodSurrent = 144613.doprint () setelah MethodCurrent = 144613.doprint () setelah MethodSurentor = 14463737373737373
Ada dua cara untuk menggunakan Loghandler sebelum timhandler:
(1) Ada atribut urutan dalam aspek, dan jumlah atribut urutan adalah urutan silang titik fokus
(2) Tentukan loghandler sebelum timhandler. Spring menggunakan urutan definisi aspek sebagai urutan tenun secara default.
2. Saya hanya ingin menenun beberapa metode ke dalam antarmuka
Cukup ubah ekspresi pointcut:
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http:/schema http://www.springframework.org/schema/beans/spring-weans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <bean id="helloWorldImpl1" /> <bean id="helloWorldImpl2" /> <bean id="timeHandler" /> <bean id="logHandler" /> <aop:config> <aop:aspect id="time" ref="timeHandler" order="1"> <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.print*(..))" /> <aop:before method="printTime" pointcut-ref="addTime" /> <aop:after method="printTime" pointcut-ref="addTime" /> </aop:aspect> <aop:aspect id="log" ref="logHandler" order="2"> <aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.do*(..))" /> <aop:before method="LogBefore" pointcut-ref="printLog" /> <aop:after method="LogAfter" pointcut-ref="printLog" /> </aop: aspek> </aop: config> </boy>
Ini berarti bahwa TimHandler hanya akan menenun metode yang dimulai pada awal HelloWorld Interface Print, Loghandler hanya akan menenun metode yang dimulai pada awal HelloWorld Interface Do
3. Force CGlib untuk menghasilkan proxy
Seperti disebutkan sebelumnya, Spring menggunakan proxy dinamis atau cGlib untuk menghasilkan proxy. Versi pegas yang lebih tinggi akan secara otomatis memilih apakah akan menggunakan proxy dinamis atau CGLIB untuk menghasilkan konten proxy. Tentu saja, kita juga dapat memaksa CGLIB untuk menghasilkan proxy, yaitu, ada atribut "proxy-target-class" di <aop: config>. Jika nilai atribut ini diatur ke true, maka proxy berbasis kelas akan berfungsi. Jika proxy-target-Class diatur ke false atau atribut ini dihilangkan, maka proxy berbasis antarmuka akan berfungsi.
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.