Details on java templates and callback mechanisms

  • 2020-05-05 11:21:09
  • OfStack

Recently, when I saw spring's JDBCTemplete template mode call, I became very interested in templates and callbacks. I inquired some information and made some summaries.

callback function:

A callback is when the client program C calls a function A in the service program S, and then S calls a function B in C in turn at some point. For C, B is called a callback function. A callback function is just a function fragment that is implemented by the user according to the callback function call convention. A callback function is part of a workflow that determines when a function is invoked (callback). Generally speaking, C does not call B itself. C provides B for the purpose of having S call it, and C has to. Since S does not know the name of B provided by C, S will agree on the interface specification (function prototype) of B, and C will inform S that it is going to use B function by R, a function of S, through C in advance. This process is called the registration of callback function, and R is called the registration function. Both Web Service and RMI of Java use callback mechanisms to access remote server programs. The callback function contains the following features:

      1, part of the workflow;

      2. Must be declared (defined) according to the calling convention specified by the workflow;

3. The invocation time of       3 is determined by the workflow. The implementer of the callback function cannot directly call the callback function to realize the workflow function.  

callback mechanism:

A callback mechanism is a common design model that exposes a function within a workflow to an external consumer at an agreed interface, providing data to the external consumer, or requiring the external consumer to provide data.

java callback mechanism:

There are always certain interfaces between software modules, which can be divided into three categories: synchronous invocation, callback and asynchronous invocation.

Synchronous call: a blocking call in which the caller waits for the other party to complete its execution before returning. It is a one-way call.

Call back to      : a two-way invocation mode, that is, the called party will also call the other party's interface when the interface is called;

Asynchronous invocation: a mechanism that resembles a message or event but invokes in the opposite direction, with the service of the interface actively notifying the client when a message or event occurs.

Callbacks are closely related to asynchronous calls: callbacks are used to register asynchronous messages, and asynchronous calls are used to notify messages.

callback instance

1. Callback interface


public interface Callback {

   String callBack();
 }

2. Caller


public class Another {
  private Callback callback;
  // Calls methods of the implementation class 
  public void setCallback(Callback callback) {
    this.callback = callback;
  }
    // Specific methods of the implementation class are called by delegate when the business needs them 
  public void doCallback(){
    System.out.println(callback.callBack());
  }
}

3. Test the callback function


public class TestCallcack {
  public static void main(String[] args) {
    // Creates the caller's implementation class 
    Another another = new Another();
    // Registers the callback interface in the implementation class 
    another.setCallback(new Callback() {  
      @Override
      public String callBack() {
        return "you are a pig";
      }
    });
    // Execute the callback function 
    another.doCallback();
  }
}

The use of callback methods typically occurs during the use of "java interfaces" and "abstract classes." The template method design pattern USES the method callback mechanism, which first defines the algorithm skeleton for a particular step and then delays some steps to a subclass to implement the design pattern. The template method design pattern allows subclasses to redefine certain steps of an algorithm without changing its structure.

Applicability of template-style design patterns:

1. Implement the invariant part of an algorithm at once, and leave the variable algorithm to the subclass.

2. The common behavior in each subclass should be extracted and consolidated in a common parent class to avoid code duplication.

3. You can control subclass extension.

template instance:

Abstract template method class:


public abstract class AbstractSup {
    // Methods that require subclasses to implement 
  public abstract void print();
    // Template method 
  public void doPrint(){
    System.out.println(" Execute template method ");
    for (int i = 0; i < 3; i++) {
      print();
    }
  }
}

Subclass implements the template mode class:


public class SubClass extends AbstractSup{
  @Override
  public void print() {
    System.out.println(" Implementation of subclasses ");
  }

}

Template method test class:


public class TempleteTest {
  public static void main(String[] args) {
    SubClass subClass = new SubClass();
    subClass.print();
    subClass.doPrint();
  }
}

Below is an in-depth look at the use of the spring template method, with JdbcTemplete as an example, detailing the use of template patterns and callback mechanisms.
Let's start with a classic example of JDBC programming:


public List<User> query() { 
 
  List<User> userList = new ArrayList<User>(); 
  String sql = "select * from User"; 
 
  Connection con = null; 
  PreparedStatement pst = null; 
  ResultSet rs = null; 
  try { 
    con = HsqldbUtil.getConnection(); 
    pst = con.prepareStatement(sql); 
    rs = pst.executeQuery(); 
 
    User user = null; 
    while (rs.next()) { 
 
      user = new User(); 
      user.setId(rs.getInt("id")); 
      user.setUserName(rs.getString("user_name")); 
      user.setBirth(rs.getDate("birth")); 
      user.setCreateDate(rs.getDate("create_date")); 
      userList.add(user); 
    } 
 
 
  } catch (SQLException e) { 
    e.printStackTrace(); 
  }finally{ 
    if(rs != null){ 
      try { 
        rs.close(); 
      } catch (SQLException e) { 
        e.printStackTrace(); 
      } 
    } 
    try { 
      pst.close(); 
    } catch (SQLException e) { 
      e.printStackTrace(); 
    } 
    try { 
      if(!con.isClosed()){ 
        try { 
          con.close(); 
       } catch (SQLException e) { 
          e.printStackTrace(); 
        } 
      } 
    } catch (SQLException e) { 
      e.printStackTrace(); 
    } 
     
  } 
  return userList; 
}


A simple query requires a whole bunch of things to do, and exceptions to handle, which we can't help but comb through:
1. Get connection
2. Get statement
3. Get resultset
4. Traverse resultset and wrap it into the collection
5. Turn off connection,statement,resultset in turn, and consider all kinds of exceptions, etc.

If more than one query produces more duplicate code, then you can use the template mechanism. By observing that most of the above steps are repetitive and reusable, only the step of traversing ResultSet and encapsulating it into a collection is customizable, because each table maps to a different java bean. This part of the code is not reusable, only custom.

Abstract class code:


public abstract class JdbcTemplate { 
 
  // Template method 
  public final Object execute(String sql) throws SQLException{
   
    Connection con = HsqldbUtil.getConnection(); 
    Statement stmt = null; 
    try { 
  
      stmt = con.createStatement(); 
      ResultSet rs = stmt.executeQuery(sql); 
      Object result = doInStatement(rs);// Abstract method (custom method, subclass implementation is required)   
      return result; 
    } 
    catch (SQLException ex) { 
       ex.printStackTrace(); 
       throw ex; 
    } 
    finally { 
  
      try { 
        stmt.close(); 
      } catch (SQLException e) { 
        e.printStackTrace(); 
      } 
      try { 
        if(!con.isClosed()){ 
          try { 
            con.close(); 
          } catch (SQLException e) { 
            e.printStackTrace(); 
          } 
        } 
      } catch (SQLException e) { 
        e.printStackTrace(); 
      } 
       
    } 
  } 
   
  // Abstract methods (custom methods) 
  protected abstract Object doInStatement(ResultSet rs); 
}

This abstract class encapsulates the main flow of SUN JDBC API, and the step of traversing ResultSet is placed in the abstract method doInStatement(), which is implemented by the subclass.

Subclass implementation code:


public class JdbcTemplateUserImpl extends JdbcTemplate { 
 
  @Override 
  protected Object doInStatement(ResultSet rs) { 
    List<User> userList = new ArrayList<User>(); 
     
    try { 
      User user = null; 
      while (rs.next()) { 
 
        user = new User(); 
        user.setId(rs.getInt("id")); 
        user.setUserName(rs.getString("user_name")); 
        user.setBirth(rs.getDate("birth")); 
        user.setCreateDate(rs.getDate("create_date")); 
        userList.add(user); 
      } 
      return userList; 
    } catch (SQLException e) { 
      e.printStackTrace(); 
      return null; 
    } 
  } 
 
}

In the doInStatement() method, we iterate over ResultSet and return.

Test code:


String sql = "select * from User"; 
JdbcTemplate jt = new JdbcTemplateUserImpl(); 
List<User> userList = (List<User>) jt.execute(sql); 

The use of the template mechanism ends there, but if it is inconvenient to inherit from the parent class above every time jdbcTemplate is called, the callback mechanism will work.  

A callback is an interface passed in a method parameter, and when the parent class calls the method, it must call the implementation class of the interface passed in the method.

The callback plus template pattern implements

Callback interface:


public class Another {
  private Callback callback;
  // Calls methods of the implementation class 
  public void setCallback(Callback callback) {
    this.callback = callback;
  }
    // Specific methods of the implementation class are called by delegate when the business needs them 
  public void doCallback(){
    System.out.println(callback.callBack());
  }
}
0

  template method:


public class Another {
  private Callback callback;
  // Calls methods of the implementation class 
  public void setCallback(Callback callback) {
    this.callback = callback;
  }
    // Specific methods of the implementation class are called by delegate when the business needs them 
  public void doCallback(){
    System.out.println(callback.callBack());
  }
}
1

Class tested:


public class Another {
  private Callback callback;
  // Calls methods of the implementation class 
  public void setCallback(Callback callback) {
    this.callback = callback;
  }
    // Specific methods of the implementation class are called by delegate when the business needs them 
  public void doCallback(){
    System.out.println(callback.callBack());
  }
}
2


Why does spring use Callback instead of the traditional templating approach?
Imagine if there were 10 abstract methods in the parent class, and all the subclasses that inherit it had to implement all 10 abstract methods. What if a subclass needs to customize only one of the methods in its parent class? This is where the Callback callback comes in.

In addition, the above approach basically implements the template method + callback pattern. But jdbcTemplate is still some way from spring. We implemented the template method + callback pattern above, but Spring's JdbcTemplate is a bit ugly. Spring introduces the concepts of RowMapper and ResultSetExtractor. The RowMapper interface is responsible for processing a row of data; for example, we can manipulate a row of records in the mapRow method, or encapsulate them as entity. ResultSetExtractor is the data set extractor, responsible for traversing ResultSet and processing the data according to the rules in RowMapper. The difference between RowMapper and ResultSetExtractor is that RowMapper processes a row of data and returns an entity object. ResultSetExtractor processes a data set and returns a collection of objects.

Of course, the above is just the basic principle of the Spring JdbcTemplte implementation. Spring JdbcTemplate does more things internally, such as encapsulating all the basic operations into the JdbcOperations interface and using JdbcAccessor to manage DataSource and transform exceptions.

The above is the entire content of this article, I hope to help you with your study.


Related articles: