Java read source code design mode: Adapter Adapter

Source: Internet
Author: User
Tags getmessage string format throwable log4j

Adapter Mode related source code:slf4j-1.6.1, hibernate-3.6.7


We all know that. Log4j is a widely used log tool, in addition to that. Sun also has its own log tool in the JDK, which is java.util.logging.Logger.

There are, of course, some other logging tools.

A variety of logging tools function and use similar, generally include debug, info, warn, error and other log level methods, but did not implement a common interface. This is not like JDBC. Although there are many types of relational databases. such as MySQL, Oracle, and so on, but a unified interface, that is, JDBC.


Of course. Suppose you write a project yourself, just find a log tool to use. However, the authors of some open source frameworks are more entangled. He doesn't know what kind of logging tool your system is using. I don't know which log tool he uses in the open source framework.

The SLF4J provides a common interface. and implements the adapter for different log tools. So the log in the open source framework only needs to invoke the interface provided by SLF4J, without needing to care about which implementation class is being used. For example, the ORM framework hibernate log relies on slf4j.

Similar to SLF4J, there are commons-logging and so on.


Source code (because the source code is huge, the following faces omit extraneous code):

SLF4J provides a unified interface Org.slf4j.Logger that is provided to the client (such as Hibernate) to invoke:

Package Org.slf4j;public Interface Logger {public boolean istraceenabled ();  public void Trace (String msg);  public void Trace (String format, Object Arg);  public void Trace (String format, Object arg1, Object arg2);  public void Trace (String format, object[] argarray);  public void Trace (String msg, Throwable t);  public boolean isdebugenabled ();  public void Debug (String msg);  public void Debug (String format, Object Arg);  public void Debug (String format, Object arg1, Object arg2);  public void Debug (String format, object[] argarray);  public void Debug (String msg, Throwable t);  public boolean isinfoenabled ();  public void info (String msg);  public void info (String format, Object Arg);  public void info (String format, Object arg1, Object arg2);  public void info (String format, object[] argarray);  public void info (String msg, Throwable t);  public boolean iswarnenabled ();  public void warn (String msg);  public void warn (String format, Object Arg); public void warn (String format,Object[] argarray);  public void warn (String format, Object arg1, Object arg2);  public void warn (String msg, Throwable t);  public boolean iserrorenabled ();  public void error (String msg);  public void error (String format, Object Arg);  public void error (String format, Object arg1, Object arg2);  public void error (String format, object[] argarray); public void error (String msg, Throwable t);}

In Clienthibernate, the log4j or JDK logger is not called directly. Instead, use the Org.slf4j.Logger interface. Take a snippet of the log in hibernate:

(Note: Loggerfactory.getlogger How to realize this article does not need to pay attention to)

Package Org.hibernate.impl;import Org.slf4j.logger;import Org.slf4j.loggerfactory;public final class Sessionfactoryimpl implements Sessionfactory, Sessionfactoryimplementor {private static final Logger log = Loggerfactory . GetLogger (sessionfactoryimpl.class);p rivate void ReadObject (ObjectInputStream in) throws IOException, classnotfoundexception {log.trace ("deserializing"); In.defaultreadobject (); Log.debug ("deserialized:" + uuid);} private void WriteObject (ObjectOutputStream out) throws IOException {Log.debug ("serializing:" + uuid); o Ut.defaultwriteobject (); Log.trace ("serialized");}}

The log4j and JDK logger do not implement the SLF4J Org.slf4j.Logger interface, so slf4j to provide an adapter to implement the Org.slf4j.Logger interface. The adapter goes to invoke the log4j or JDK logger to implement the log, which enables the logging tool to be compatible. (Note: The source code can see that the Locationawarelogger interface inherits Org.slf4j.Logger so the implementation of Locationawarelogger is equivalent to implementing the Org.slf4j.Logger)

LOG4J Adapter Org.slf4j.impl.Log4jLoggerAdapter:

Package Org.slf4j.impl;import Java.io.serializable;import Org.apache.log4j.level;import org.slf4j.Logger;import Org.slf4j.marker;import Org.slf4j.helpers.formattingtuple;import Org.slf4j.helpers.messageformatter;import    Org.slf4j.spi.locationawarelogger;public Final class Log4jloggeradapter extends Markerignoringbase implements  Locationawarelogger, Serializable {final transient org.apache.log4j.Logger Logger;  public Boolean isdebugenabled () {return logger.isdebugenabled ();  } public void Debug (String msg) {Logger.log (FQCN, Level.debug, MSG, NULL); public void Debug (String format, Object Arg) {if (logger.isdebugenabled ()) {formattingtuple ft = Messageforma      Tter.format (format, ARG);    Logger.log (FQCN, Level.debug, Ft.getmessage (), ft.getthrowable ()); }} public void Debug (String format, Object arg1, Object arg2) {if (logger.isdebugenabled ()) {Formattingtuple      FT = Messageformatter.format (format, arg1, arg2); Logger.log (FQCN, Level.debug, FT.getmessage (), ft.getthrowable ()); }} public void Debug (String format, object[] argarray) {if (logger.isdebugenabled ()) {formattingtuple ft = Me      Ssageformatter.arrayformat (format, argarray);    Logger.log (FQCN, Level.debug, Ft.getmessage (), ft.getthrowable ());  }} public void Debug (String msg, Throwable t) {logger.log (FQCN, Level.debug, MSG, T); }}

JDK Logger Adapter Org.slf4j.impl.JDK14LoggerAdapter:

Package Org.slf4j.impl;import Java.util.logging.level;import Org.slf4j.marker;import Org.slf4j.helpers.formattingtuple;import Org.slf4j.helpers.markerignoringbase;import Org.slf4j.helpers.messageformatter;import Org.slf4j.spi.locationawarelogger;public Final Class JDK14LoggerAdapter  Extends Markerignoringbase implements Locationawarelogger {final Java.util.logging.Logger Logger;  public Boolean isdebugenabled () {return logger.isloggable (level.fine);    public void Debug (String msg) {if (logger.isloggable (level.fine)) {log (self, level.fine, MSG, NULL); }} public void Debug (String format, Object Arg) {if (logger.isloggable (Level.fine)) {formattingtuple ft = Mes      Sageformatter.format (format, ARG);    Log (self, level.fine, ft.getmessage (), ft.getthrowable ()); }} public void Debug (String format, Object arg1, Object arg2) {if (logger.isloggable (level.fine)) {formatting      Tuple ft = Messageformatter.format (format, arg1, arg2); Log (self, LeVel.    FINE, Ft.getmessage (), ft.getthrowable ()); }} public void Debug (String format, object[] argarray) {if (logger.isloggable (Level.fine)) {Formattingtuple F      t = Messageformatter.arrayformat (format, argarray);    Log (self, level.fine, ft.getmessage (), ft.getthrowable ());  }} public void Debug (String msg, Throwable t) {if (logger.isloggable (level.fine)) {log (self, level.fine, MSG,    T); }  }}

In adapter mode, the following sections are generally included:

adaptee: a real implementation class that implements functionality, but is incompatible with the client. This is the Java.util.logging.Logger, Org.apache.log4j.Logger in the above code.


Target: The interface that is called to the client and the adapter implements this interface. Is the Org.slf4j.Logger in the above code.

Adapter: Adapter, adapter implements target interface, detailed function calls Adaptee to implement. It is the Org.slf4j.impl.Log4jLoggerAdapter and org.slf4j.impl.JDK14LoggerAdapter above.

Client: invokes the target interface.

is the hibernate above.


Summarize:

There are many similar classes (such as Java.util.logging.Logger, Org.apache.log4j.Logger), there is no unified interface, but the client wants to be compatible. In this case, the best way to do this is to refactor, that is, let them implement the same interface. However, it is assumed that refactoring costs are too large or that the same interface cannot be implemented at all (such as the example above). log4j and JDK Logger are not one at all), they must create a unified interface (i.e. Org.slf4j.Logger). and write an adapter for each class (that is, Org.slf4j.impl.Log4jLoggerAdapter, Org.slf4j.impl.JDK14LoggerAdapter). Allow the adapter to implement a unified interface, and invoke a detailed implementation class to implement, has achieved compatibility purposes.


Fork Brother reproduced please indicate the source: http://blog.csdn.net/xiao__gui/article/details/32695647



Java read source code design mode: Adapter Adapter

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.