2017-02-12 6 views
6

मैं जावा सीख रहा हूँ और मुझे लगता है कई कार्यक्षमताओं कि मानकीकृत कर रहे हैं देखते हैं कि:कैसे SLF4J/JPA/JAX-RS उनके कार्यान्वयन को ढूंढते हैं?

  • लॉगिंग (SLF4J का प्रयोग करके)
  • हठ (जेपीए का प्रयोग करके)
  • बाकी (JAX-रुपये का प्रयोग करके)
  • सोप (JAX-WS उपयोग करते हुए)
  • आदि

चलो Sl4j उदाहरण लेते: इसे सही ढंग से उपयोग करने के लिए log4j के साथ, हम sl4j api, sl4j/log4j पुल और log4j कार्यान्वयन आयात करना है।

प्रश्न: मेरी कक्षा में, मैं केवल Slf4j API के साथ संवाद करता हूं।

मेरा आवेदन log4j कार्यान्वयन के बारे में कैसे जानता है? क्या कोई बता सकता है कि हुड के नीचे क्या हो रहा है?

सादर

+0

क्या आप 'log4j-over-slf4j' मॉड्यूल के बारे में बात कर रहे हैं? – Andremoniy

+0

मेरे मामले में, 'sl44' के माध्यम से' log4j' का उपयोग करने के लिए, मेरे पास निम्नलिखित JARs हैं: 'slf4j-api', 'log4j-core' और' log4j-sl4j-impl' – Kevin

+1

संभावित डुप्लिकेट [slf4j कैसे बाध्य करता है कार्यान्वयन? क्या यह वास्तव में संकलन समय के दौरान ऐसा करता है?] (Http://stackoverflow.com/questions/17829995/how-does-slf4j-bind-to-implementation-does-it-really-do-so-during-compile-time) – sm4

उत्तर

4

ओपी कुछ सामान्य मामलों में कार्यान्वयन के बारे में एक सामान्य प्रश्न पूछता है।

कई जवाब में तृप्त के रूप में लॉग इन करना, SLF4J इंटरफ़ेस देता है और log4j-slf4j कार्यान्वयन देता है।

जब आप निम्न कथन का उपयोग करें:

public static ILoggerFactory getILoggerFactory() { 
     if (INITIALIZATION_STATE == UNINITIALIZED) { 
      synchronized (LoggerFactory.class) { 
       if (INITIALIZATION_STATE == UNINITIALIZED) { 
        INITIALIZATION_STATE = ONGOING_INITIALIZATION; 
        performInitialization(); 
       } 
      } 
     } 
     switch (INITIALIZATION_STATE) { 
     case SUCCESSFUL_INITIALIZATION: 
      return StaticLoggerBinder.getSingleton().getLoggerFactory(); 
     } 
     ... 
    } 

:

हम getLogger विधि LoggerFactory class में घोषित से Logger प्राप्त करने की कोशिश:

import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory; 
    ... 
    private static final Logger LOG = LoggerFactory.getLogger(FooBarClass.class); 
    ... 
    LOG.debug("Foobar"); 

यह क्या हो रहा है है तो जादू उस कथन पर होता है:

return StaticLoggerBinder.getSingleton().getLoggerFactory(); 

क्योंकि क्लासपाथ जानता है कि आपने कार्यान्वित किया है, क्यों StaticLoggerBinder कार्यान्वयन is provided by log4j। हम देख सकते हैं के रूप में, log4j अपने स्वयं के कार्यान्वयन के साथ एक प्रदान करता है:

private final ILoggerFactory loggerFactory; 
... 
private StaticLoggerBinder() { 
    loggerFactory = new Log4jLoggerFactory(); 
} 

और बस हो गया!

हठ

जेपीए/हाइबरनेट भाग के लिए, आप hibernate-jpa-api और hibernate-* (कोर, entitymanager, आदि) को शामिल करने के लिए है।

import javax.persitence.EntityManagerFactory 
    import javax.persitence.Persistence; 
    ... 
    private static EntityManagerFactory EMF = Peristence.createEntityManagerFactory("foobar", null); 

List और ArrayList का सवाल है, अपने classpath इंटरफेस और जार आप आयात करना कार्यान्वयन धन्यवाद के साथ तंग आ गया है:

मान लीजिए कि आप बनाने के लिए एक EntityManagerFactory चाहते हैं।

EntityManagerFactoryhibernate-jpa-api से आता है जहां हमारे पास Persistence class है। हम देख सकते हैं कि createEntityManagerFactory विधि पहले सभी प्रदाताओं सूचीबद्ध करती है और उनमें से प्रत्येक के लिए, createEntityManagerFactory निकाल दिया जाता है। यह वह जगह है जहां hibernate आता है। यह HibernatePersistenceProvider प्रदान करता है जो implements the PersistenceProvider class प्रदान करता है।

इस प्रकार Hibernate इंजेक्शन दिया गया है।

2

आप, slf4j वालों से निपटने की तरह के बारे में बात कर रहे हैं:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FooClass.class); 

तो यह बहुत आसान है: org.slf4j.Logger सिर्फ एक इंटरफेस है, जो कई कार्यान्वयन है। उपयोग पुस्तकालय slf4j-log4j12 के मामले में, इस इंटरफ़ेस वर्ग org.slf4j.impl.Log4jLoggerAdapter जो आंतरिक रूप से

final transient org.apache.log4j.Logger logger;

शामिल द्वारा कार्यान्वित किया जाता तो यह सरल एडाप्टर जो आपके प्रवेश अनुरोध लपेटता है और log4j लकड़हारा वस्तु पर उन्हें आह्वान है:

public void debug(String msg) { 
    logger.log(FQCN, Level.DEBUG, msg, null); 
} 

अधिक विशेष रूप से, उचित Logger कार्यान्वयन LoggerFactory द्वारा उत्पादित किया गया है जो पहले Log4jLoggerFactory

के माध्यम से बनाता है
StaticLoggerBinder.getSingleton().getLoggerFactory() 

, बाद में Log4jLoggerAdapter उदाहरण की आवश्यकता है।


आम तौर पर यह अनुकूलन स्तर के माध्यम से काम करता है documentation से img पर दिखाए गये की तरह:

enter image description here

2

Slf4jlog4j या किसी अन्य अंतर्निहित प्रवेश करने पुस्तकालय के साथ इस्तेमाल किया जा सकता।

log4j के मामले में, यह log4j-slf4j-impl.jar का उपयोग करता है जिसमें log4j लाइब्रेरी के साथ संचार के लिए आवश्यक कक्षाएं होती हैं।

प्रति documentation के रूप में -

SLF4J निष्पादन में प्रवेश कार्यान्वयन का समाधान नहीं होता है, लेकिन एक ब्रिजिंग एपीआई के साथ संकलन पर सीधे । एसएलएफ 4 जे के जेएआर से अधिक आपको निम्नलिखित जेएआर की आवश्यकता है: ब्रिजिंग जेएआर और के जेएआर कार्यान्वयन। यहाँ तुम क्या Log4J साथ मिलता है:

Slf4j-log4j Integration

1

SLF4J मैनुअल घेरा SLF4J के तहत कैसे कार्यान्वयन उपयोग करने के लिए ढूँढता है को संदर्भित करता है: Binding with a logging framework at deployment time

जैसा कि पहले उल्लेख, SLF4J विभिन्न प्रवेश चौखटे का समर्थन करता है:

SLF4J के रूप में "SLF4J बाइंडिंग" बात (Logback, Log4J, आदि ...) कि एक कार्यान्वयन का उपयोग करने की अनुमति देता है संदर्भित करता है। कई जार फ़ाइलों के साथ SLF4J वितरण जहाजों को "SLF4J बाइंडिंग" के रूप में संदर्भित किया गया है, प्रत्येक बाध्यकारी समर्थित ढांचे के अनुरूप है।

आपके पास SLF4J के कार्यान्वयन के रूप में कई SLF4J बाइंडिंग हैं। और निश्चित रूप से, एक कार्यान्वयन एपीआई हो सकता है अलग "SLF4J बाइंडिंग" अपने संस्करण के अनुसार:

प्रवेश चौखटे स्विच करने के लिए, बस अपने वर्ग पथ पर slf4j बाइंडिंग की जगह। उदाहरण के लिए, java.util.logging से log4j पर स्विच करने के लिए, slf4j-jdk14-1.7.22.jar को slf4j-log4j12-1.7.22.jar के साथ प्रतिस्थापित करें।

कार्यान्वयन के साथ बाध्यकारी रनटाइम पर नहीं किया जाता है लेकिन संकलन समय पर: प्रत्येक SLF4J बाध्यकारी संकलन समय पर एक और केवल एक विशिष्ट लॉगिंग ढांचे का उपयोग करने के लिए कठिन होता है।
तो, तुम सिर्फ SLF4J classpath में बाध्यकारी शामिल करने के लिए (उदाहरण के लिए slf4j-jdk14-1.7.22.jar) ताकि SLF4J इसे इस्तेमाल करता है:

SLF4J किसी विशेष वर्ग लोडर मशीनरी पर निर्भर नहीं करता । वास्तव में, प्रत्येक SLF4J बाध्यकारी एक और केवल एक विशिष्ट लॉगिंग ढांचे का उपयोग करने के लिए संकलित समय पर हार्डवार्ड किया जाता है। उदाहरण के लिए, slf4j-log4j12-1.7.22.jar बाइंडिंग log4j का उपयोग करने के लिए संकलित समय पर बाध्य है। आपके कोड में, slf4j-api-1.7.22.jar के अतिरिक्त, आप बस उपयुक्त कक्षा पथ स्थान पर अपनी पसंद का केवल एक बाध्यकारी छोड़ दें। अपनी कक्षा पथ पर एक से अधिक बाध्यकारी न रखें। यहां सामान्य विचार का एक ग्राफिकल चित्रण है।

यही कारण है कि आमतौर पर क्लासपाथ पर एक से अधिक एसएलएफ 4 जे बाध्यकारी रखने की सलाह दी जाती है क्योंकि एसएलएफ 4 जे को रनटाइम पर कार्यान्वयन का चयन करने के लिए डिज़ाइन नहीं किया गया है।

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