动态代理的分类
- 基于接口的动态代理(JDK的动态代理)
- 基于类的动态代理(cglib的动态代理)
核心 : InvocationHandler 和 Proxy
额外的彩蛋:
获取类的是三种方法:
-
通过实例对象获取(实例对象.getClass();)//启动类加载器
-
通过类名.class获取(类名.calss) //扩展类加载器/jvm平台类加载器
-
通过类的静态方法获取(Class.forName("全类名"))(建议使用)//应用类加载器
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类 - 类名.class:通过类名的属性class获取
* 多用于参数的传递 - 对象.getClass():getClass()方法在Object类中定义着。
* 多用于对象的获取字节码的方式
第一步创建接口
package Proxy;
/**
*学生管理接口
*/
public interface StudntMapper {
public void add();
public void del();
public void update();
public void query();
}
第二步:
package Proxy;
/**
* @Description: 学生管理的实现,也就是需要增强的类
*/
public class StudentMapperImpl implements StudntMapper {
public void add() {
System.out.println("添加学生");
}
public void del() {
System.out.println("删除学生");
}
public void update() {
System.out.println("修改学生");
}
public void query() {
System.out.println("查询学生");
}
}
第三步:动态代理的实现
package Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Description: 动态代理的实现
*/
public class ProxyInvocationHandler implements InvocationHandler {
//需要增强的接口实现类
private StudentMapperImpl studentMapper;
//接口的实现类对象的注入
public void setStudentMapper(StudentMapperImpl studentMapper) {
this.studentMapper = studentMapper;
}
//生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy() {
//import java.lang.reflect.Proxy;
return Proxy.newProxyInstance(this.getClass().getClassLoader(), studentMapper.getClass().getInterfaces(), this);
}
// proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//被增强的方法
log(method.getName());
//核心:本质利用反射实现!
Object invoke = method.invoke(studentMapper, args);
return invoke;
}
//增加的方法。
public void log(String mag){
System.out.println("调用了"+mag+"方法");
}
}
第四步:
package Proxy;
public class Client {
public static void main(String[] args) {
//真实对象
StudentMapperImpl studentMapper = new StudentMapperImpl();
//代理对象的调用处理程序
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
//设置要代理的对象
proxyInvocationHandler.setStudentMapper(studentMapper);
//动态生成StudntMapper接口的代理类!
StudntMapper proxy = (StudntMapper) proxyInvocationHandler.getProxy();
proxy.add();
proxy.del();
proxy.update();
proxy.query();
}
}