MyBatis-02-01-MyBatis's dynamic proxy and static proxy mechanism and Demo


Dynamic proxy mechanism

Insert picture description here

API provided by traditional MyBatis

Insert picture description here

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

Insert picture description here

There is a one-to-one correspondence between the left and right interfaces and id.

Insert picture description here

Insert picture description here

Static proxy and dynamic proxy

Distinguish the key: whether these three entities exist in the program operation stage
Insert picture description here

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();
	}

}

Insert picture description here

Insert picture description here
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

Insert picture description here

Dynamic proxy

Project structure

Insert picture description here

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();
	}

}

Guess you like

Origin blog.csdn.net/qq_44627608/article/details/115351636