动态代理,增加原来实现类的功能

动态代理的分类

  • 基于接口的动态代理(JDK的动态代理)
  • 基于类的动态代理(cglib的动态代理)
    核心 : InvocationHandler 和 Proxy

额外的彩蛋:
获取类的是三种方法:

  •   通过实例对象获取(实例对象.getClass();)//启动类加载器
    
  •   通过类名.class获取(类名.calss)	//扩展类加载器/jvm平台类加载器
    
  •   通过类的静态方法获取(Class.forName("全类名"))(建议使用)//应用类加载器
    
  1. Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
    * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
  2. 类名.class:通过类名的属性class获取
    * 多用于参数的传递
  3. 对象.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();
    }
}

Guess you like

Origin blog.csdn.net/m0_57184607/article/details/120695631