JAVA反射和动态代理

我的博客 原文地址,点击访问

JAVA反射和动态代理

1. 反射

1. 反射机制的定义:

反射是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制。

2. 反射的作用:

1、动态地创建类的实例,将类绑定到现有的对象中,或从现有的对象中获取类型。

2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类

3.应用
  • 获取其Class对象的时候不,类不会被加载,当通过Class.forName()获取其类对象引用的时候类会被加载
public class Main {
    public static void main(String[] args) {
        // 不会初始化静态块
        Class clazz1 = String.class;
        System.out.println("------");
        // 会初始化
        Class clazz2 = Class.forName("java.lang.String");
    }
}

2.动态代理——JDK动态代理

JDK动态代理只提供接口的代理,不支持类的代理

代码示例
  • 接口
public interface Project {

    String sayHello(String name);

    void sayBay();
}
  • 实现类
public class RealProject implements Project{
    public String sayHello(String name) {
        System.out.println("你好"+name);
        return "你好"+name;
    }

    public void sayBay() {
        System.out.println("ByeBye");
    }
}
  • 动态代理类
public class InvocationHandlerImpl implements InvocationHandler {

    private Project project;

    public InvocationHandlerImpl(Project project) {
        this.project = project;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我在调用之前...");
        
        //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        Object returnValue = method.invoke(project, args);

        //在代理真实对象后我们也可以添加一些自己的操作
        System.out.println("我在调用之后...");

        return returnValue;
    }

}
  • 测试类
public class Test {

    public static void main(String[] args) throws Throwable {
        //代理的真实对象
        Project realSubject = new RealProject();

        //传入了真实的对象,代理方法会调用真实对象的方法
        InvocationHandler handler = new InvocationHandlerImpl(realSubject);

        //该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
        ClassLoader loader = realSubject.getClass().getClassLoader();
        Class[] interfaces = realSubject.getClass().getInterfaces();
        Project project = (Project) Proxy.newProxyInstance(loader, interfaces, handler);
        System.out.println("动态代理对象:"+project.getClass().getName());

        project.sayBay();
        System.out.println("-----------------------------------");
        Object[] args2 = new Object[1];
        args2[0] = "zlz";
        handler.invoke(realSubject, Project.class.getMethod("sayHello", String.class), args2);
    }
}

运行结果:
动态代理对象:com.sun.proxy.$Proxy0
我在调用之前...
ByeBye
我在调用之后...
-----------------------------------
我在调用之前...
你好zlz
我在调用之后...

第一种方法通过 Proxy.newProxyInstance()方法创建代理对象。

代理对象的类型是com.sun.proxy.$Proxy0 指向了 Project 类型的引用project。

执行project.sayBay()方法时。最终还是像第二个方法一样,调用代理处理器实现类的invoke()方法,实现动态代理,执行三部曲:

  1. 前置方法输出我在调用之前…
  2. 调用被代理对象的sayHello()方法
  3. 后置方法输出我在调用之后…

我的博客 原文地址,点击访问

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值