Article Directory
Dynamic proxy mechanism
API provided by traditional MyBatis
The statement ID parameter passed in cannot be checked error
Mapper interface
Using the Mapper interface, MyBatis abstracts each <mapper> element in the configuration file as a Mapper interface, and the method declared in this interface corresponds to the <select|update|delete|insert> child element in the <mapper> element
There is a one-to-one correspondence between the left and right interfaces and id.
Static proxy and dynamic proxy
Distinguish the key: whether these three entities exist in the program operation stage
On the left is the target entity, on the right is the agent entity, and on the top is the interface.
The following two entities are both to implement the above interface. The
proxy entity can extend the real entity
Static proxy
An interface for handing in assignments
Two implementation classes, student and class
leader. The class leader has students as parameters. The
test class instantiates the class leader and the student and assigns values, and implements the method of viewing assignment corrections by calling the class leader’s attributes.
Project structure
Master.java class leader
package com.mybatis.demo;
//代理类
public class Master implements Submitted{
private Student student;
//实现抽象方法
@Override
public void submitHomework() {
student.submitHomework();
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
Student.java student class
package com.mybatis.demo;
//被代理类
public class Student implements Submitted{
private String name;
//实现接口的方法
@Override
public void submitHomework() {
System.out.println(name+"交作业");
}
//get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Need to implement the interface
package com.mybatis.demo;
public interface Submitted {
//代理类与被代理类都需要实现的接口
public void submitHomework();
}
Test.java test class
package com.mybatis.demo;
public class Test {
public static void main(String[] args) {
Master master=new Master();
Student student=new Student();
student.setName("九爷");
master.setStudent(student);
fun(master);
}
//参数是接口,只要实现了接口,具体对象是谁无所谓
public static void fun(Submitted sub) {
sub.submitHomework();
}
}
The upper left is the proxy class and the interface that
the proxy class needs to implement. The bottom is a class, which needs us to define
Dynamic proxy
Project structure
MyInvocationHandler.java
package com.mybatis.demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler<T> implements InvocationHandler {
//被代理对象的类型,接口的类型,通用的T类型
T obj;
//重写此方法
//动态代理的核心
//代理类中,每个方法被调用时候都会执行此方法
//参数1:动态代理对象
//参数2:正在执行的方法
//参数3:是参数2的传入的实际参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//通过反射执行代理类的方法
//参数1:需要被执行的方法,参数2:实际参数
Object result = method.invoke(obj, args);
//可以对代理的那个方法进行扩展
System.out.println("这是方法的扩展");
return null;
}
//封装出现代理类对象的方法
public T createProxySubject() {
//生成代理实例
//参数1:类加载器
//参数2:class数组,参数类需要实现的接口类型
//参数3:InvocationHandler类型
return (T) Proxy.newProxyInstance(Student.class.getClassLoader(),
new Class[] {
Submitted.class},
this);
}
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
Student.java proxy class
package com.mybatis.demo;
//被代理类
public class Student implements Submitted{
private String name;
//实现接口的方法
@Override
public void submitHomework() {
System.out.println(name+"交作业");
}
//get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Submitted.java interface classes that need to be implemented
package com.mybatis.demo;
public interface Submitted {
//代理类与被代理类都需要实现的接口
public void submitHomework();
}
Test.java test class
package com.mybatis.demo;
public class Test {
public static void main(String[] args) {
//动态代理
Student s=new Student();
s.setName("张三");
//动态生成代理对象,(模拟SqlSession中的GetMapper方法的实现)
MyInvocationHandler<Student> invo=new MyInvocationHandler<>();
invo.setObj(s);
Submitted sub=invo.createProxySubject();
fun(sub);
}
//参数是接口,只要实现了接口,具体对象是谁无所谓
public static void fun(Submitted sub) {
sub.submitHomework();
}
}