Java:反射动态代理

Java:反射
Java:设计模式
Java:反射动态代理
各位读者请注意:以上连续三篇(包括本篇),属于引导型博客,并不是对知识点的详细解释,而是对“反射、设计模式和反射动态代理”这三个知识模块的个人理解型的白话文。对于初学java,尤其是别的语言转java语言的同学来说应该可以有不小帮助,对于“想要钻研深入的技术的同学”,可以忽略本文。

一、反射与工厂模式

1.工厂模式的缺点

class WorkFactory {
    public WorkFactory() {
    }

    public static Worker getInstance(String className) {
        if ("student".equals(className)) {
            return new Student();
        } else if ("teacher".equals(className)) {
            return new Teacher();
        } else {
            return null;
        }
    }
}

可以看到工厂模式中,如果需要新增子类,那么就要修改WorkFactory的接口,如下:

class WorkFactory {
    public WorkFactory() {
    }

    public static Worker getInstance(String className) {
        if ("student".equals(className)) {
            return new Student();
        } else if ("teacher".equals(className)) {
            return new Teacher();
        } else if ("cooker".equals(className)) {
            return new Cooker();//增加一个Cooker子类就得修改一次
        } else {
            return null;
        }
    }
}

2.引入反射后就能解决这个缺点

因为Class类可以使用newInstance() 实例化对象,同时Class.forName()能够接收类名称,如下

class WorkFactory {
    public WorkFactory() {
    }

    public static Worker getInstance(String className) {
        //不再是添加一个子类就new一个对应的对象,而是统一使用反射后的Class类使用newInstance()实例化对象
        Worker worker = null;
        try {
            worker = (Worker) Class.forName(className).newInstance() ;
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return worker ;
    }
}

public class test {
    public static void main(String[] args) {
        Worker worker = WorkFactory.getInstance("Student");
        worker.doWork();

        worker = WorkFactory.getInstance("Teacher");
        worker.doWork();
    }
}

二、反射与代理模式(动态)

1.什么是动态代理

上篇Java:设计模式中简单讲了静态代理模式,其特点就是:一个被代理类对应一个代理类,当有多个被代理类时,静态代理模式就需要设计多个代理类,很不方便,那么动态代理模式就是解决这个问题的设计模式,它可以使用一个代理类来代理多个不同的被代理类。

2.动态代理模式的核心部分

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

class ProxySubject implements InvocationHandler {
    // 绑定任意接口的对象,使用Object描述
    private Object proxy_obj;

    //这是一个自定义方法,作用有两个:
    //1.给“被代理类”的对象实例化
    //2.返回一个“代理类”的对象
    public Object bind(Object obj) { 
        this.proxy_obj = obj;
        
        //绑定“被代理类”实现的所有接口,取得“代理类” 
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

	//当“代理类”的对象调用“被代理类”的“重写方法”时,就会转为调用该方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //执行proxy_obj对象中参数为args的方法,返回值类型为Object
        Object ret = method.invoke(this.proxy_obj, args);
        return ret;
    }
}

3.动态代理模式代码示例

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

public class test {
    public static void main(String[] args) {
        Worker worker = (Worker) new ProxySubject().bind(new Teacher());
        worker.doWork();//打印"教师改作业"

        worker = (Worker) new ProxySubject().bind(new Student());
        worker.doWork();//打印"学生写作业"
    }
}

interface Worker {
    void doWork();
}

class Teacher implements Worker {

    @Override
    public void doWork() {
        System.out.println("教师改作业");
    }
}

class Student implements Worker {

    @Override
    public void doWork() {
        System.out.println("学生写作业");
    }
}

class ProxySubject implements InvocationHandler {
    private Object proxy_obj;
    
    public Object bind(Object obj) {
        this.proxy_obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object ret = method.invoke(this.proxy_obj, args);
        return ret;
    }
}

4.运行结果

在这里插入图片描述

三、最后可以总结一下动态代理的作用

我的总结不够精简,Java 动态代理作用是什么?这个知乎贴里有各路大神的精辟总结!!!

猜你喜欢

转载自blog.csdn.net/w_y_x_y/article/details/85060901