Alibaba P7 dos lados: ¿Por qué no se pueden sobrecargar los métodos en el mapeador de la interfaz Mybatis? ¡Recibí la oferta directamente después de responder!

El prólogo es importante

La función del agente dinámico: a través de la devolución de llamada del método interceptor, se mejora el método de destino.
La implicación es mejorar el método objetivo. La frase anterior es correcta, pero no creas que es la verdad Como todos saben, los agentes dinámicos también tienen la hegemonía de lanzar látigo para detener el flujo, e incluso el objetivo objetivo no requiere un modelo de ciencia ficción.

Nota: Este artículo asume que el lector comprende el principio de proxy dinámico. Si no comprende el significado de objetivo, es difícil comprender este artículo. Se recomienda comprender primero el proxy dinámico.

Algunas preguntas de la entrevista recopiladas en el último 2020 (todas organizadas en documentos), hay muchos productos secos, incluidas explicaciones detalladas de mysql, netty, primavera, hilo, nube de primavera, etc., también hay planes de estudio detallados, preguntas de la entrevista, etc. Siento que estoy en la entrevista Esta sección es muy clara: para obtener la información de la entrevista, simplemente: ¡  haga clic aquí para obtenerla! ! Contraseña: 51CTO

Alibaba P7 dos lados: ¿Por qué no se pueden sobrecargar los métodos en el mapeador de la interfaz Mybatis?  ¡Recibí la oferta directamente después de responder!

1. Personalice el proxy dinámico JDK para realizar el mapeador automático Mapper

Primero define un pojo.

public class User {
  private Integer id;
  private String name;
  private int age;

  public User(Integer id, String name, int age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
  // getter setter
}
再定义一个接口UserMapper.java。
public interface UserMapper {
  public User getUserById(Integer id);  
}

A continuación, echemos un vistazo a cómo usar el proxy dinámico para transmitir y eliminar la transmisión, realizar la interfaz de creación de instancias y llamar al método de interfaz para devolver datos.
Personalice un InvocationHandler.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MapperProxy implements InvocationHandler {

  @SuppressWarnings("unchecked")
  public <T> T newInstance(Class<T> clz) {
    return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] { clz }, this);
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {
      try {
        // 诸如hashCode()、toString()、equals()等方法,将target指向当前对象this
        return method.invoke(this, args);
      } catch (Throwable t) {
      }
    }
    // 投鞭断流
    return new User((Integer) args[0], "zhangsan", 18);
  }
}

El objetivo en el código anterior, cuando se ejecuta el método en Object.java, el objetivo apunta a esto, y el objetivo se ha convertido en una marioneta, un símbolo y un marcador de posición. Ya no hay objetivo en la intercepción.
Escribe un código de prueba:

public static void main(String[] args) {
  MapperProxy proxy = new MapperProxy();

  UserMapper mapper = proxy.newInstance(UserMapper.class);
  User user = mapper.getUserById(1001);

  System.out.println("ID:" + user.getId());
  System.out.println("Name:" + user.getName());
  System.out.println("Age:" + user.getAge());

  System.out.println(mapper.toString());
}

salida:

ID:1001
Name:zhangsan
Age:18
x.y.MapperProxy@6bc7c054

Este es el principio de implementación subyacente del Mapper Mapper automático Mybatis.
Algunos lectores pueden no dejar de preguntarse: ¿Cómo se escribe el código como escribe un principiante? No hay estructura y falta belleza.

Hay que decir que como maestro experimentado, que puede escribir programas como principiantes, debe ser un maestro. Esto puede hacer que los principiantes se sientan cordiales, cómodos y acordes con su propio estilo, y que ellos o ellos sientan que el código escrito por las vacas grandes no es más que eso, e incluso pueden escribir mejor que los escritos por las vacas grandes. Desde entonces, están llenos de confianza. El entusiasmo es alto, pensando que la brecha con Daniel está a solo tres minutos para el final.

2. Análisis del código fuente de Mybatis automatic mapper Mapper

Primero escribe una clase de prueba:

public static void main(String[] args) {
    SqlSession sqlSession = MybatisSqlSessionFactory.openSession();
    try {
      StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
      List<Student> students = studentMapper.findAllStudents();
      for (Student student : students) {
        System.out.println(student);
      }
    } finally {
      sqlSession.close();
    }
  }

Mapper se ve así:

public interface StudentMapper {
  List<Student> findAllStudents();
  Student findStudentById(Integer id);
  void insertStudent(Student student);
}
org.apache.ibatis.binding.MapperProxy.java部分源码。
public class MapperProxy<T> implements InvocationHandler, Serializable {

  private static final long serialVersionUID = -6424540398559729838L;
  private final SqlSession sqlSession;
  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethod> methodCache;

  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {
      try {
        return method.invoke(this, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
    // 投鞭断流
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }
  // ...

org.apache.ibatis.binding.MapperProxyFactory.java parte del código fuente.

public class MapperProxyFactory<T> {

  private final Class<T> mapperInterface;

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

Así es como Mybatis usa agentes dinámicos para cortar el flujo.

3. ¿Se pueden sobrecargar los métodos de la interfaz Mapper? (importante)

Similar a lo siguiente:

public User getUserById(Integer id);
public User getUserById(Integer id, String name);

Respuesta: No.

Razón: Mybatis usa el nombre completo del paquete + método Mapper + como clave para encontrar el único sql en xml para ejecutar. Similar: key = xyUserMapper.getUserById, entonces, sobrecargar el método causará conflictos. Para la interfaz Mapper, Mybatis prohíbe la sobrecarga de métodos (overLoad).

Nota: Al estudiar, primero se estudia el código fuente y se comprende el principio. Al escribir una publicación de blog, explique el principio primero y luego lea el código fuente. El orden es todo lo contrario. Espero que los lectores no se confundan por esto, pensando que soy demasiado fuerte para ser un profeta.

Al final:

Algunas preguntas de la entrevista recopiladas en el último 2020 (todas organizadas en documentos), hay muchos productos secos, incluidas explicaciones detalladas de mysql, netty, primavera, hilo, nube de primavera, etc., también hay planes de estudio detallados, preguntas de la entrevista, etc. Siento que estoy en la entrevista Esta sección es muy clara: para obtener la información de la entrevista, simplemente: ¡ haga clic aquí para obtenerla! ! Contraseña: 51CTO

Alibaba P7 dos lados: ¿Por qué no se pueden sobrecargar los métodos en el mapeador de la interfaz Mybatis?  ¡Recibí la oferta directamente después de responder!

Supongo que te gusta

Origin blog.51cto.com/14969174/2547738
Recomendado
Clasificación