Monta kertaa olemme huomanneet, että 3rd party kirjastot kirjoittaa System.out tai System.err. Olisi luultavasti helpompaa uudelleen suoraan näiden yhteisten puunkorjuun puitteita, mutta se ei ole.
Alla luokka, jonka avulla voit saavuttaa juuri tämän. Luokka on esimerkki PrintWriter ja voidaan instantiated ja käyttää System.out ja System.err PrintWriter. Se uudelleen suoraan kaikki STDOUT ja stderr viestejä Commons Logging. Se myös etsiä kutsuvan luokan ja saada metsuri nimillä: com.domain.Class (valinnaisesti käyttäjän määrittämän etuliite tai suffiksi, kuten: STDOUT.com.
domain.Class tai com.domain.Class.STDOUT)
helppokäyttöisyys voit käyttää staattisia tehdas menetelmiä, jotka automaattisesti rekisteröi luokassa STDOUT tai stderr vastaavasti. Alla on muutamia tyypillisiä esimerkkejä sanan käytöstä
Muutama huomio siitä, miten se toimii:
PrintWriter huuhtelu (): n jälkeen koko linja on painettu, rivinvaihto kohdataan, tai tavutaulukkoa kirjoitetaan.
Käyttö esimerkiksi: alussa hakemuksesi:
julkinen staattinen void main (String [] args) {CommonsLoggingPrintStream.registerOnStdout (null "STDOUT '); CommonsLoggingPrintStream.registerOnStderr (null," stderr "); //...
}
Käyttö esimerkiksi: Keväällä (lisätä seuraavan käynnistyksen yhteydessä käyttää tehtaan menetelmiä joten koodia ei tarvita) :
STDOUTSTDERR
Class Code (huomautus: voit vapaasti muuttaa paketti /classname, niitä käytetään koodin anaylize kutsupinon, mutta ne katsoin ylös dynaamisesti)
paketti mycommons.logging, tuonti java.io.ByteArrayOutputStream, tuonti java.io.IOException, tuonti java.io.PrintStream, tuonti java.util.Locale, tuonti java.util.concurrent.locks.ReentrantLock, tuonti org.apache.commons.logging.
LogFactory; /** * Tämä luokka uudelleen ohjaa kaikki pyynnöt PrintStream (jota STDOUT ja stderr) * ja lähettää ne Commons Logging. * * Kutsumus menetelmä PrintStream määritetään analysoimalla kutsupinon. * * Käytä mukavuutta menetelmiä registerOnStdout ja registerOnStderr automaattisesti * luoda esimerkiksi tämän luokan ja rekisteröi sen virran ohjata * Commons Logging. * * Esimerkki Tyypillinen käyttö: * * * public static void main (String [] args) {* CommonsLoggingPrintStream.registerOnStdout (null, "STDOUT"); * CommonsLoggingPrintStream.registerOnStderr (null, "stderr"); * //...
*} * * * Huomautus kumma tapauksissa: Jos teet useita puheluja menetelmiä, jotka eivät laukaise * värin, kuten edellä PrintWriter (esimerkiksi liittää (char)) kutsuvan menetelmä * päätetään ainoastaan lopullinen puhelu, joka laukaisee värin tai puhelut huuhtelu () suoraan. myös huomata, että * tässä tapauksessa sinun täytyy synkronoida pääsy näitä menetelmiä, koska ne eivät kierrä turvallinen.
* On yleisesti suositeltavaa vain soittaa menetelmiä, jotka tuottavat automaattinen huuhtelu kuvatulla * vuonna PrintWriter Javadocs * /public class CommonsLoggingPrintStream ulottuu PrintStream {LoggingOutputStream OutputStream; yksityinen ReentrantLock lukko = uusi ReentrantLock (); /** * Voit käyttää uutta esimerkiksi kirjata kaikki PrintStream menetelmiä Commons Logging.
* Viestit kirjoitetaan CommonsLogging kun huuhtelu () kutsutaan käyttäen * samoja sääntöjä kuin PrintStream käyttää kanssa autoFlush = true * *param prependName nimi prepended luokan (nolla = ei) nimi kuin: registerOnStdout ("STDOUT" , null) johtaa lokiviestiä kuten: INFO STDOUT.org.mydomain.MyClass - Kirjaudu viesti *param postpendName nimi postpended luokkaan (nolla = ei) nimi kuin: registerOnStdout (null, "STDOUT") tulokset lokiin viestin, kuten: INFO org.mydomain.MyClass.
STDOUT -Log viesti * /public CommonsLoggingPrintStream (String prependName, String postpendName) {tämä (uusi LoggingOutputStream (prependName, postpendName, CommonsLoggingPrintStream.class.getCanonicalName ())); } Yksityinen CommonsLoggingPrintStream (LoggingOutputStream los) {Super (los, true); this.outputStream = los; } /** * Convenience menetelmä - Luo uuden esiintymä * CommonsLoggingPrintStream ja rekisteröi sen STDOUT * *param prependName nimi prepended luokan (nolla = ei) nimi kuin: registerOnStdout ("STDOUT", null) johtaa lokiviestiä kuten: INFO STDOUT.org.mydomain.
MyClass - Kirjaudu viesti *param postpendName nimi postpended luokkaan (nolla = ei) nimi kuin: registerOnStdout (null, "STDOUT") johtaa lokiviestiä tällaisen kuten: INFO org.mydomain.MyClass.STDOUT -Log viesti *return viittaus CommonsLoggingPrintStream objekti luotu, voidaan jättää huomiotta useimmissa tilanteissa * /public static CommonsLoggingPrintStream registerOnStdout (String prependName, String postpendName) {CommonsLoggingPrintStream tuomari = uusi CommonsLoggingPrintStream ( prependName, postpendName); System.
setOut (viite); palata viite; } /** * Convenience menetelmä - Luo uuden esiintymä * CommonsLoggingPrintStream ja rekisteröi se vakiovirhetulosteessa * *param prependName nimi prepended luokan (nolla = ei) nimi kuin: registerOnStdout ("stderr", null) johtaa lokiviestiä kuten: INFO STDERR.org.mydomain.MyClass - Kirjaudu viesti *param postpendName nimi postpended luokkaan (nolla = ei) nimi kuin: registerOnStdout (null, "stderr") johtaa lokiviestiä tällaisen kuten: INFO org.mydomain.MyClass.
STDERR -Log viesti *return viittaus CommonsLoggingPrintStream objekti luotu, voidaan jättää huomiotta useimmissa tilanteissa * /public static CommonsLoggingPrintStream registerOnStderr (String prependName, String postpendName) {CommonsLoggingPrintStream tuomari = uusi CommonsLoggingPrintStream ( prependName, postpendName); System.setErr (viite); palata viite; } /** * Tämä luokka on tarpeen hyödyntää PrintWriters taata * että huuhtelu kutsutaan sopivana ajankohtana. Meidän lähettää tiedot * Commons Loggging vasta huuhtelu () on kehottanut kääritty tuotanto * virtaan PrintWriter.
* * /Private static luokka LoggingOutputStream ulottuu ByteArrayOutputStream {private String currentCallerName; yksityinen String prependName = null; yksityinen String postpendName = null; yksityinen String outerClassName = null; //Tämä on dynaamisesti syntyy siten, että paketin muutoksista tai luokan nimi eivät vaikuta toimintoihin julkisen LoggingOutputStream (String prependName, String postpendName, String outerClassName) {this.prependName = (prependName! = Null &&! PrependName.isEmpty ()) ? prependName + "." : ""; this.postpendName = (postpendName! = null &&! postpendName.isEmpty ())? ".
" + PostpendName: ""; this.outerClassName = outerClassName; }Override Public void huuhtelu () throws IOException {super.flush (); //Kirjaudu tuloksena tavua jälkeen huuhtelu () kutsutaan. Voimme luottaa tähän, koska //loimme PrintStream kanssa autoFlush vaihtoehto päällä. //Jos tavutaulukkoa kirjoitetaan se voi sisältää useita rivejä String [] logMessages = this.toString (). Split ("\\ n"); for (String viesti: logMessages) {LogFactory.getLog (currentCallerName) .info (message.trim ()); }} Void setNameOfCaller () {boolean reachedCallToOutterClass = false; StackTraceElement [] pinon = Thread.
currentThread (). GetStackTrace (); //Loop läpi pinon hivenaineiden kunnes löydämme "java.io.PrintStream" //ja palauta ensimmäinen täysin pätevä-luokan-nimen jälkeen puhelut PrintStream varten (StackTraceElement e: pino) {jos (e.getClassName () .equals (outerClassName)) {reachedCallToOutterClass = true; jatkaa; } Else if (reachedCallToOutterClass) {this.currentCallerName = prependName + e.getClassName () + postpendName; palata; }} This.currentCallerName = "unknown.classname"; //Tavoiteta koodi (tai niin Teorian)}} /** * Siirtää puhelun ja outputStream.
setNameOfCaller () vain * jos synkronoitu lukko tämä omistaa kerran. Jos se * omistaa enemmän kuin kerran, tämä on soittopyynnön sisällä * PrintWriter, tilanne joka vaikeuttaa /mahdotonta * määrittää kutsuvan menetelmä, eikä se ole tarpeen, koska * ensimmäinen puhelu setNameOfCaller () on kaikki, että oli * määrittämiseksi tarvittavat kutsuvan menetelmä. * /Yksityinen void setNameOfCaller (ReentrantLock lukko) {jos (lock.getHoldCount ()>