2012-11-13 11 views
9

साथ स्वचालित रूप से मैं डेटाबेस कॉल के साथ एक वर्ग है, और मैं आम तौर पर log4j के साथ इस वर्ग में (तर्क के साथ) कहा जाता है हर विधि प्रवेश करना चाहते हैं:कैसे मैं एक वर्ग में कहा जाता है कि हर विधि प्रवेश कर सकते हैं log4j

logger.debug("foo(id="+id+") initiated"); 

क्या यह स्वचालित रूप से ऐसा करना संभव है? हो सकता है कि प्रत्येक विधि की शुरुआत में प्रत्येक प्रकार की लॉन्ग.डेबग लिखने के बजाय एनोटेशन का उपयोग करें?

आज मुझे अपने लॉगिंग को अद्यतन करना होगा। जब भी मैं तर्क या विधि नाम बदलता हूं तो मुझे लॉगिंग करना होगा।

+0

एओपी कोशिश करने लायक हो सकता है। – Nishant

उत्तर

5

यदि आपके पास उन तरीकों की घोषणा करने वाले इंटरफेस हैं जिन्हें आप कॉल लॉग करना चाहते हैं, तो आप जो चाहते हैं उसे प्राप्त करने के लिए मानक प्रॉक्सी API का उपयोग कर सकते हैं।

प्रॉक्सी एपीआई आपको अपने वास्तविक कार्यान्वयन को एक नई, प्रॉक्सी क्लास में लपेटने की अनुमति देगा, जो कॉल लॉग करेगा, और अग्रेषित करने के लिए कॉल अग्रेषित करेगा। आपको बस एक InvocationHandler लागू करना है जो लॉगिंग और अग्रेषण करता है।

उदाहरण के लिए,

interface Calculator { 
    int add(int a, int b); 
} 

class CalculatorImpl implements Calculator { 
    @Override public int add(int a, int b) { return a+b; } 
} 

class LoggingInvocationHandler implements InvocationHandler { 
    private final Object delegate; 
    public LoggingInvocationHandler(final Object delegate) { 
    this.delegate = delegate; 
    } 
    @Override invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    System.out.println("method: " + method + ", args: " + args); 
    return method.invoke(delegate, args); 
    } 
} 

class X { 
    public static void main(String... args) { 
    final Calculator calc = new CalculatorImpl(); 
    final Calculator loggingCalc = 
     (Calculator) Proxy.newProxyInstance(X.class.getClassLoader(), 
              new Class[] {Calculator.class}, 
              new LoggingInvocationHandler (calc)); 
    loggingCalc.add(2, 3); // shall print to the screen 
    } 
} 

तुम भी आसानी से, बस InvocationHandler में कोड बदलकर वापसी मूल्यों और अपवाद तरीकों द्वारा फेंका प्रवेश कर सकते हैं। इसके अलावा, उदाहरण के तौर पर आप System.out.println की बजाय किसी भी लॉगिंग फ्रेमवर्क का उपयोग कर सकते हैं।

वापसी मूल्यों और अपवाद लॉग इन करने के लिए, आप की तरह कुछ कर सकता है:

@Override invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    System.out.println("method: " + method + ", args: " + args); 
    try { 
     final Object ret = method.invoke(delegate, args); 
     System.out.println("return: " + ret); 
     return ret; 
    } catch (Throwable t) { 
     System.out.println("thrown: " + t); 
     throw t; 
    } 
    } 
4

एक संभव समाधान AspectJ उपयोग करने के लिए किया जाएगा। आइडिया प्रत्येक विधि को पहलू संलग्न करना होगा जिसे आप लॉग करना चाहते हैं, और एक विधि के बजाय लॉगिंग करना पहलू है। पहलू लॉगिंग का एक उदाहरण right here in stackoverflow है।

@Loggable(Loggable.INFO) 
public String load(URL url) { 
    return url.openConnection().getContent(); 
} 

सभी विधि कॉल SLF4J के माध्यम से लॉग इन कर रहे:

संबंधित मुद्दे