动态代理的简单创建

前言

        本篇简单介绍动态代理及动态代理的创建过程。


一、动态代理功能与创建

        动态代理是可以在不更改原来代码的基础上,增强方法的,本质上其实就是给原来的类找了一个代理,所有功能都可以交给代理,需要增强的功能让代理增强,而不需要增强的方法,可以由代理在重新掉原有类的方法来执行。

        由于代理需要拿到原有类的功能,所有需要原有类先实现一个接口,可以理解为原有类重写了此接口的方法。

        首先先创建一个类和一个接口,并给此接口写一些方法使类实现此接口。

        接口代码,如下:给两个方法,一个是eat的方法,一个是study方法

public interface Person {
    void eat();
    void study();
}

         定义一个学生类,由于get,set方法不使用,只写了getName方法,所以省略,并重写eat、study方法:

public class Student implements Person {
    private String name;
    private int age;
    private String gender;

    public Student() {
    }

    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }

    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void study() {
        System.out.println("学习");
    }
}

        我们就可以对方法进行增强,Proxy.newProxyInstance()可以创建代理里面需要传入三个参数,第一个是类加载器,类的字节码对象通过getClassLoader()方法获取类加载器。第二个是接口的字节码文件,第三个则是需要增强的方法。

        代码如下:

public class Test {
    public static void main(String[] args) {
        //创建一个对象
        Student student=new Student("张三",18,"男");
        //创建代理
            Person person = (Person) Proxy.newProxyInstance(
                student.getClass().getClassLoader(),
                new Class[]{Person.class},
                new InvocationHandler() {
                    //重写方法,用于增强方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //增强eat方法,是可以键盘录入,并打印输出键盘录入的姓名和调用方法的对象一起吃饭
                        if (method.getName().equals("eat")) {
                            Scanner scanner=new Scanner(System.in);
                            String name=scanner.next();
                            System.out.println(name+"和"+student.getName()+"一起吃饭");
                        } else if (method.getName().equals("study")) {
                            //使用invoke调用对象本身函数.
                            method.invoke(student,args);
                        }
                        //因为本身不需要返回值,直接返回null即可
                        return null;
                    }
                });
        person.eat();
        person.study();
    }
}

        这个就是对eat方法进行了增强,本身只是输出吃饭,而增强后则是可以键盘录入和谁一起吃饭,而又与无需对study方法进行重写,所以直接调用对象原有的方法即可。

二、对ArrayList集合进行增强

        我们也可以对原有的方法进行增强,例如ArrayList集合是没有去重功能的,我们可以对其中的add方法进行增强,给其添加去重功能。

        代码如下:

public class Test2 {
    public static void main(String[] args) {
        //先创建一个集合
        List<Integer> list = new ArrayList<>();
        //创建代理
        List<Integer> newList = (List<Integer>) Proxy.newProxyInstance(
                list.getClass().getClassLoader(),
                new Class[]{List.class},
                new InvocationHandler() {
                    //重写add方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //判断是否用户调用的是否是add方法,若不是则调用原有方法
                        if (method.getName().equals("add")) {
                            //判断将要添加的数据是否在集合中,,若不在,则添加到集合中,否则直接返回false
                            if (!list.contains(args[0])) {
                                method.invoke(list, args[0]);
                            }else {
                                return false;
                            }
                        } else {
                            method.invoke(list, args[0]);
                        }
                        return true;
                    }
                }
        );
        //测试
        newList.add(12);
        newList.add(13);
        newList.add(12);
        System.out.println(list);
    }
}

总结

        本篇介绍了动态代理和简单的创建过程,以及简单的增强了ArrayListt的add方法

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值