Java学习【动态代理】

动态代理还是了解的比较有限…


在这里插入图片描述

静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同的父类

静态代理的局限性:只能代理某一类型接口的实例,不能做到任意接口任意方法的操作,同时如果需要代理多个类的时候,每个委托类都要编写一个代理类,会导致代理类繁多,不好管理。

代理步骤:

1、定义一个接口,所有需要委托(被代理)类都实现该接口

//Mapper.java
package Proxy.StaticProxy;

public interface Mapper {
    public void jdbcOpera();
}

2、定义一个委托(被代理)类,在jdbcOpera()方法中编写业务代码

//UserMapper.java
package Proxy.StaticProxy;

public class UserMapper implements Mapper{
    public void jdbcOpera(){
        System.out.println("===========执行User核心业务代码==");
    }
}

3、定义一个代理类,其中再调用被代理类的方法

package Proxy.StaticProxy;

public class StaticProxy {
    public void startJdbcOpera(Mapper mapper){	//接口作为参数
        System.out.println("开始代理");
        //调用被代理对象的业务处理
        mapper.jdbcOpera();
        System.out.println("代理结束");
    }
}

4、定义一个测试类

package Proxy.StaticProxy;

public class Test {
    public static void main(String[] args) {
    	//创建被代理对象
        UserMapper userMapper = new UserMapper();
        //创建代理对象
        StaticProxy sp =  new StaticProxy();
        //代理对象开始代理
        sp.startJdbcOpera(userMapper);
    }
}

在这里插入图片描述

JDK动态代理

JDK动态代理灵活性很大,在任意时候任意地方都可以使用任意功能,前提是该对象有接口

一些重要的方法:

  1. java.lang.reflect.Proxy:这是Java动态代理机制的主类,他提供了一组静态方法来为一组接口动态地生成代理类及其对象。

  2. Proxy类的newProxyInstance方法用于动态生成代理对象

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
}
  1. java.lang.reflect.InvocationHandler:这是进行实际业务增强处理的类,他自定义类一个invoke方法,通常在该方法中实现对委托类的代理访问。

    InvocationHandler的核心方法invoke方法,该方法负责集中处理动态代理类上的所有方法调用。

    public Object invoke(Object o, Method method, Object[] args)
    第一个参数:动态代理类实例;第二个参数:被调用的方法对应的Method对象;第三个参数:被调用的方法中声明的参数
    

代理步骤:

1)创建自定义调用处理器

1.1、创建自定义调用处理器并实现java.lang.InvocationHandler接口,由它来实现invoke方法,执行代理函数。
1.2、定义一个方法获取动态生成代理对象,其中调用Proxy.newProxyInstance:分别传入类加载器被代理接口调用处理器
1.3、通过重写InvocationHandler接口中唯一的invoke方法进行业务增强处理

package Proxy.Dynamic;

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

/**
 * 实现InvocationHandle接口
 * InvocationHandler接口中声明了一个invoke方法,invoke方法是实际进行业务增强处理
 */
public class MyHandler implements InvocationHandler {
    //声明被代理对象,目标
    private Object target;
    public MyHandler(){

    }

    public MyHandler(Object target){
        this.target = target;
    }

    //定义方法,获取动态生成代理对象
    public Object getProxyInstance(){
        //通过Proxy类的newProxyInstance方法,动态生成“中介”
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    /**
     *
     * @param o         动态生成的代理对象的实例
     * @param method    被代理对象当前正在执行的业务方法
     * @param args      被代理对象当前正在执行的业务方法中的参数
     * @return
     * @throws Throwable
     */
    //通过invoke方法进行业务增强处理
    @Override
    public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        System.out.println("===========获取数据库连接===");
        method.invoke(target,args);
        System.out.println("=========关闭连接=======");

        return null;
    }
}
2)定义接口
//UMapper.java
package Proxy.Dynamic;

public interface UMapper {
    public void jdbcOpera();
}
3)定义被代理类,其实现上述接口,并写下业务代码
//UserMapper.java
package Proxy.Dynamic;

public class UserMapper implements UMapper {
    public void jdbcOpera(){
        System.out.println("===========执行User核心业务代码==");
    }
}
4)测试类
//Test.java
package Proxy.Dynamic;

public class Test {
    public static void main(String[] args) {
        //创建代理对象
        UserMapper userMapper = new UserMapper();

        MyHandler myHandler = new MyHandler(userMapper);
        //获取动态代理
        UMapper mi =  (UMapper) myHandler.getProxyInstance();
        mi.jdbcOpera();
    }
}
参考:

https://xz.aliyun.com/t/9197
https://www.bilibili.com/video/BV1N4411672a

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值