美文网首页
动态代理的一个demo示例

动态代理的一个demo示例

作者: 12313凯皇 | 来源:发表于2021-12-15 21:54 被阅读0次

最近在看动态代理设计模式,但是看完之后还是模模糊糊不太清楚,于是决定自己写一个小的demo来加深印象。

举个例子:
现在有一个学生列表,我们可以从服务器拉取学生列表,也可以向服务器添加一个学生名单。

这些方法最终实现的步骤都是相似的:都需要向服务器发起请求,只是请求url和参数可能不一样,如果每个方法都单独写的话,那么以后每增加一个方法都需要加一段冗余代码。所以这里就可以通过动态代理来实现。

首先,创建一个自定义注解用于标记请求链接:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface GET {

    String value();
}

接着,定义学生相关类:

public class Student {

    public long id;
    public String name;

    public Student(long id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

public interface StudentService {

    @GET("student/getStudents")
    void getStudents();

    @GET("student/addStudent")
    void addStudent(Student student);
}

最后,实现一个动态代理类:

public class RequestProxy {

    public static RequestProxy create() {
        return new RequestProxy();
    }

    public <T> T getService(Class<T> service) {
        //noinspection unchecked
        return (T) Proxy.newProxyInstance(
                service.getClassLoader(),
                new Class[]{service},
                RequestProxy.this::invoke);
    }

    private Object invoke(Object o, Method method, Object[] objects) {
        GET methodAnnotation = method.getAnnotation(GET.class);
        if (methodAnnotation != null) {
            String value = methodAnnotation.value();
            System.out.println("------request start------");
            System.out.println(method.getName() + "方法被调用,向" + value + "发送请求");
            System.out.println("请求参数:" + contentToString(objects));
            System.out.println("------request end------\n");
        }
        return null;
    }

    private String contentToString(Object[] objects) {
        if (objects == null || objects.length == 0) return null;
        StringBuilder builder = new StringBuilder("[");
        for (Object o : objects) {
            builder.append(o.toString()).append(",");
        }
        return builder.substring(0, builder.length() - 1) + "]";
    }

}

测试代码:

public class Test {

    public static void main(String[] args) {
        StudentService studentService = RequestProxy.create().getService(StudentService.class);
        studentService.getStudents();
        studentService.addStudent(new Student(1, "Bob"));

    }
}

最终输出:

------request start------
getStudents方法被调用,向student/getStudents发送请求
请求参数:null
------request end------

------request start------
addStudent方法被调用,向student/addStudent发送请求
请求参数:[Student{id=1, name='Bob'}]
------request end------

Demo写的比较简陋,核心在invoke方法中,每个动态代理类的方法都会走到这个方法中去,具体的实现就需要看具体的业务逻辑了。

相关文章

网友评论

      本文标题:动态代理的一个demo示例

      本文链接:https://www.haomeiwen.com/subject/pttmfrtx.html