Selama beberapa waktu di pekerjaan yang berbeda, saya menemukan kebutuhan untuk beberapa utilitas yang saya tidak dapat temukan tersedia pada saat itu. Dan saya melihat bahwa saya membutuhkannya beberapa kali berulang kali. Jadi saya menulis perpustakaan kecil saya sendiri yang saya temukan sangat berguna. Jadi saya hanya menerbitkannya sebagai perpustakaan java open-source.
Inilah tautan GithubJavadoc online tersedia di siniJuga, perpustakaan ini tersedia di Maven Central. Berikut adalah artefak Maven (versi 1.5.0.8 adalah yang terbaru pada saat penulisan artikel ini tetapi mungkin berubah di masa depan. Untuk memeriksa pencarian versi terbaru untuk artefak "MgntUtils" di
http: //search.maven. org / ):
<dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>javadoc</classifier> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>sources</classifier> </dependency>
Di bawah ini adalah penjelasan singkat tentang apa yang ada di sana. Perpustakaan dilengkapi dengan JavaDoc yang ditulis dengan baik (saya harap) dengan deskripsi rinci. Jadi di sini adalah daftar fitur:
Filter noise Stacktrace
Dalam pengalaman saya, fitur ini adalah yang paling umum dan bermanfaat bagi saya. Stacktrace adalah penyelamat saat men-debug atau mencoba mencari tahu apa yang salah dalam aplikasi Anda. Namun, ketika bekerja dengan log di sisi server Anda dapat menemukan stacktrace besar yang berisi ekor tak berguna terpanjang dari berbagai kerangka kerja dan paket Server Aplikasi terkait. Dan di suatu tempat di tumpukan ini, ada beberapa baris jejak yang relevan dan mereka mungkin berada di segmen yang berbeda dipisahkan oleh informasi yang tidak berguna. Menjadi mimpi buruk untuk mencari hal-hal yang relevan. Berikut ini adalah tautan yang menjelaskan masalah yang sama dengan contoh kehidupan nyata (bukan untuk orang jahat)
https://dzone.com/articles/filtering-stack-trace-hell . Jadi Di perpustakaan saya, Ada kelas yang disebut
TextUtils dan memiliki metode
getStacktrace () dengan beberapa tanda tangan kelebihan beban. Dibutuhkan instance Throwable dan memungkinkan untuk mengatur awalan paket dari paket yang relevan.
Juga, utilitas yang sama (mulai dari versi 1.5.0.3) memiliki metode
getStacktrace () yang mengambil antarmuka CharSequence alih-alih Throwable dan dengan demikian memungkinkan untuk menyaring dan mempersingkat stacktrace yang disimpan sebagai string dengan cara yang sama seperti stacktrace yang diekstrak dari Throwable. Jadi, pada dasarnya stacktraces dapat difilter "on the fly" pada saat run atau lambat dari sumber teks seperti log. (Hanya untuk memperjelas - utilitas tidak mendukung parsing dan memodifikasi seluruh file log. Ini mendukung penyaringan hanya stacktrace yang diteruskan sebagai String. Jadi jika ada yang ingin memfilter pengecualian dalam file log mereka harus mengurai file log dan mengekstrak stacktrace sebagai string terpisah dan kemudian dapat menggunakan utilitas ini untuk menyaring masing-masing stacktrace individu).
Ini adalah contoh penggunaan. Katakanlah kode perusahaan Anda selalu berada dalam paket yang dimulai dengan "com.plain. *" Jadi Anda menetapkan awalan seperti itu dan melakukan ini
logger.info(TextUtils.getStacktrace(e,true,"com.plain."));
ini akan menyaring dengan sangat cerdas semua bagian tak berguna dari jejak yang meninggalkan Anda dengan stacktrace yang sangat ringkas. Juga, saya merasa sangat nyaman untuk mengatur prefix dan kemudian hanya menggunakan metode kenyamanan
TextUtils.getStacktrace(e);
Itu akan melakukan hal yang sama. Untuk mempreset awalan cukup gunakan metode
setRelevantPackage("com.plain.");
Jika Anda ingin menetapkan sebelumnya nilai ini dengan konfigurasi kemudian mulai dengan pustaka versi 1.1.0.1 Anda dapat mengatur Variabel Lingkungan "
MGNT_RELEVANT_PACKAGE " atau Properti Sistem "
mgnt.relevant.package " untuk menilai "
com.plain. " Dan properti tersebut akan disetel ke nilai itu tanpa Anda memanggil metode
TextUtils.setRelevantPackage ("com.plain."); secara eksplisit dalam kode Anda. Perhatikan bahwa nilai properti Sistem akan didahulukan dari variabel lingkungan jika keduanya ditetapkan. Hanya pengingat bahwa dengan Properti sistem Anda dapat menambahkannya di baris perintah Anda menggunakan flag -D:
"-Dmgnt.relevant.package = com.plain."
Juga, jika Anda menggunakan versi lebih awal dari 1.1.0.1 dari pustaka ini atau tidak ingin menggunakan variabel Environment atau properti sistem yang disebutkan di atas dan Anda menggunakan lingkungan Spring, Anda dapat mempreset awalan dengan menambahkan segmen berikut ke konfigurasi Spring Anda:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass" value="com.mgnt.utils.TextUtils"/> <property name="targetMethod" value="setRelevantPackage"/> <property name="arguments" value="com.plain."/> </bean>
Javadoc menjelaskan semuanya secara rinci. Tapi di sini ada sedikit penggoda: Anda akan mendapatkan stacktrace berikut:
at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() ... at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() ... at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks()
bukannya
at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed() at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() at sun.reflect.NativeMethodAccessorImpl.invoke() at sun.reflect.DelegatingMethodAccessorImpl.invoke() at java.lang.reflect.Method.invoke() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod() at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.transaction.interceptor.TransactionInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept() at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks()
String Senyap mengurai menjadi Integer, Panjang, dll
TextUtils kelas yang sama menyediakan metode untuk mem-parsing String secara diam-diam (tanpa kecuali pernah dilempar) ke dalam jenis Double, Long, Integer, Short dan Byte. Metode ini disebut
parseStringToLong () parseStringToInteger () dll. Mereka semua mengambil 4 argumen:
- String yang akan diuraikan
- Implementasi Number (Double, Long, Integer, Short atau Byte) untuk berfungsi sebagai nilai default jika terjadi masalah parsing
- String yang akan dicetak sebagai pesan kesalahan ke log jika argumen pertama adalah nol (mungkin nol, dan kemudian tidak ada kesalahan yang dicetak)
- String yang akan dicetak sebagai pesan kesalahan jika NumberFormatException terjadi (mungkin nol, dan kemudian tidak ada kesalahan yang dicetak)
Parsing String ke Time Interval
Di
TextUtils kelas yang sama, ada metode
parseStringToTimeInterval (nilai String) . Metode ini mem-parsing string yang diharapkan untuk menyimpan beberapa nilai interval waktu - nilai numerik dengan akhiran unit waktu opsional. Misalnya, string "38s" akan diurai menjadi 38 detik, "24m" - 24 menit "4h" - 4 jam, "3d" - 3 hari dan "45" sebagai 45 milidetik. Sufiks yang didukung adalah "
s " untuk detik, "
m " untuk menit, "
h " selama berjam-jam dan "
d " selama berhari-hari. String tanpa akhiran dianggap memiliki nilai dalam milidetik. Sufiks tidak peka huruf besar-kecil. Jika String yang disediakan berisi akhiran yang tidak didukung atau memegang nilai numerik negatif atau nol atau memegang nilai non-numerik - maka IllegalArgumentException dilempar. Metode ini mengembalikan kelas TimeInterval - kelas yang juga ditentukan di perpustakaan ini. Pada dasarnya, ia memegang dua properti dengan getter dan setter yang relevan: "nilai" panjang dan java.util.concurrent.TimeUnit. Tetapi selain getter dan setter, kelas ini memiliki metode
toMillis () ,
toSeconds () ,
toMinutes () ,
toHours () toDays () . Metode tersebut mengembalikan nilai panjang dalam skala waktu yang ditentukan (Cara yang sama seperti metode yang sesuai di kelas
java.util.concurrent.TimeUnit )
Metode ini mungkin sangat berguna untuk mem-parsing properti interval waktu seperti batas waktu atau periode tunggu dari file konfigurasi. Ini menghilangkan perhitungan yang tidak dibutuhkan dari skala waktu yang berbeda untuk milidetik bolak-balik. Pertimbangkan bahwa Anda memiliki properti
methodInvokingInterval yang perlu Anda atur selama 5 hari. Jadi, untuk menetapkan nilai milidetik, Anda harus menghitung bahwa 5 hari adalah 432000000 milidetik (jelas bukan tugas yang mustahil tetapi menjengkelkan dan rawan kesalahan) dan kemudian siapa pun yang melihat nilai 432000000 harus menghitungnya kembali ke 5 hari-hari yang membuat frustrasi. Tetapi menggunakan metode ini Anda akan memiliki nilai properti diatur ke "5d" dan memanggil kode
long milliseconds = TextUtils.parsingStringToTimeInterval("5d").toMillis();
akan menyelesaikan masalah konversi Anda. Jelas, ini bukan fitur yang terlalu rumit, tetapi bisa menambah kesederhanaan dan kejelasan dalam file konfigurasi Anda dan menyimpan beberapa frustrasi dan kesalahan perhitungan "bodoh" ke bug milidetik.
Bandingkan Versi
Utilitas ini memungkinkan untuk mengonversi String ke versi dan sebaliknya, dan untuk membandingkan versi dan rentang versi dengan benar. Seringkali jika Anda perlu membandingkan versi, Anda hanya membandingkan Strings. Jadi katakanlah versi "1.5.3" akan lebih besar dari versi "1.3.1". Namun, jika Anda akan membandingkan Strings "1.4.2" dan "1.12.3" the String "1.4.2" keliru akan lebih besar. Jadi Utilitas ini menangani masalah seperti itu dan sebagai tambahan, memperkenalkan kelas VersionRange dan memungkinkan operasi pada rentang versi. (Lihat metode
compareVersions di kelas
TextUtils dan class
VersionRange )
Konverter string Unicode
Class
StringUnicodeEncoderDecoder memiliki metode yang dapat mengubah String (dalam bahasa apa pun) menjadi urutan karakter Unicode dan sebaliknya. Misalnya, string "Hello World" akan dikonversi menjadi
"\ u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064"
dan dapat dikembalikan kembali.
Manajemen siklus hidup (Pabrik instantiasi sendiri)
Fitur ini adalah paket yang berisi beberapa infrastruktur kecil yang menyederhanakan dan mengotomatiskan bekerja dengan Pabrik yang menyediakan implementasi konkret Antarmuka. Paket ini hanya berisi 2 kelas:
BaseEntityFactory dan
BaseEntity . Singkatnya, apa yang dilakukan infrastruktur ini adalah bahwa jika Anda membuat pabrik yang memperluas
BaseEntityFactory dan beberapa Interface dengan semua implementasi konkretnya yang memperluas
BaseEntity, maka setiap instance kelas implementasi beton Anda akan secara otomatis dimasukkan ke pabrik Anda. Anda tidak perlu khawatir tentang bagaimana dan kapan mengisi pabrik Anda. Infrastruktur akan melakukannya untuk Anda ketika konstruktor dari kelas implementasi konkret Anda dipanggil. Jadi yang harus Anda lakukan adalah membuat sejumlah kelas implementasi konkret dan memastikan bahwa untuk setiap satu konstruktor dipanggil. Setelah itu, Anda dapat menggunakan pabrik Anda untuk mendapatkan salah satu dari kelas implementasi konkret Anda di mana saja dalam kode Anda. Ini penjelasan singkat. Ada beberapa detail lagi tetapi tidak banyak. Untuk deskripsi terperinci tentang paket ini, silakan merujuk ke Javadoc API dari paket
com.mgnt.lifecycle.management description. Juga, kode sumber berisi paket com.mgnt.lifecycle.management.example yang berisi contoh kode yang dikomentari dengan baik dan terperinci tentang cara menggunakan fitur ini.
Adapun penggunaan praktis, saya merasa sangat berguna untuk kerangka kerja Spring. Ingatlah bahwa Spring membuat semua kacang yang didefinisikan selama inisialisasi. Jadi dalam konteks Spring, jika kita hanya mendeklarasikan implementasi konkret kita sebagai Spring bean, Spring akan membuat instantiate untuk kita, sehingga menginisialisasi pabrik mereka secara otomatis. Ini bisa sangat nyaman. Bayangkan bahwa Anda memiliki beberapa kacang yang memiliki properti dari jenis Antarmuka yang ditentukan pengguna yang memiliki beberapa implementasi, tetapi implementasi aktual yang diperlukan ditentukan saat runtime. Jadi pada saat itu, Anda dapat menggunakan metode
getInstance (java.lang.String) dari Pabrik Anda untuk mengakses implementasi yang diperlukan. Ini akan memungkinkan Anda untuk tidak menyuntikkan SEMUA instantiasi konkret Anda ke kacang Anda dan Anda tidak perlu menggunakan Spring
Bean Factory untuk mengakses kacang Spring yang ditentukan karena itu akan melanggar non-intrusivitas Spring (artinya Anda dapat menulis komponen yang tidak memiliki ketergantungan pada Musim semi). Juga, Jika pada tahap selanjutnya Anda perlu menambahkan lebih banyak implementasi konkret, yang harus Anda lakukan adalah menambahkan kelas implementasi ke kode Anda dan mendeklarasikannya sebagai Spring bean. Sisanya akan dilakukan oleh Spring dan infrastruktur ini!
Utilitas file
Utilitas ini memungkinkan untuk membaca file sebagai String dengan atau tanpa menentukan set karakter atau hanya membacanya sebagai array byte. Utilitas ini menggunakan paket nio dan Buffer untuk kinerja yang lebih cepat. Ukuran file maksimum untuk Utilitas ini adalah 2G.
Pemanfaatan waktu
Ini hanyalah metode kenyamanan tunggal yang menyediakan fungsionalitas yang sama dengan Thread.sleep () tetapi tidak berisik. Yaitu "menelan" IterruptedException. Juga, dibutuhkan 2 argumen: waktu untuk tidur dan unit pengukuran. Jadi, bukannya
try { Thread.sleep(2000); } catch (InterruptedException ie) { }
Anda bisa menulis:
TimeUtils.sleepFor(2, TimeUnit.SECONDS);
Saya pikir itu lucu
Jadi ini dia. Silakan mengunduh perpustakaan ini. Muncul dengan lisensi MIT - salah satu lisensi paling permisif yang saya tahu. Kode sumber, versi Javadoc dan biner tersedia di tautan di atas. Kode ini dikompilasi oleh JDK 8 tetapi tidak memiliki fitur versi 8 di dalamnya. Seharusnya bekerja dengan java 7 paling pasti, saya menduga itu akan bekerja dengan java 6 dan bahkan 5, tetapi belum mengujinya dengan versi tersebut. Jangan ragu untuk menggunakannya sesuai keinginan Anda, beri tahu orang lain tentang hal itu jika Anda suka dan kirimkan saya pesan di michael_gantman@yahoo.com jika Anda memiliki umpan balik.