Java基础之02 动态代理模式172 173 类加载器原理分析

动态代理
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。

  • java动态代理主要是使用java.lang.reflect包中的两个类。

InvocationHandler类

  • public Object invoke(Object obj,Method method,Object[] obs)
    其中第一个参数 obj 指的是代理类,method是被代理的方法,obs是指被代理的方法的参数组。此方法由代理类来实现。

Proxy类

  • protected Proxy(InvocationHandler h);
  • static Class getProxyClass(ClassLoader loader,Class[] interfaces);
  • static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);

动态代理其实是在运行时生成class
所以,我们必须提供一组interface,然后告诉他class已经实现了这些interface,
而且在生成Proxy的时候,必须给他提供一个handler,让他来接管实际的工作。


接口Subject

package com.vince.proxy;

/**
 * Created by vince on 2017/6/13.
 */
public interface Subject {
    public void shopping();
}

package com.vince.proxy;

/**
 * Created by vince on 2017/6/13.
 */
public interface Hotel {
    public void reserve();
}


Person人来实现接口

package com.vince.proxy;

/**
 * Created by vince on 2017/6/13.
 */
public class Person implements Subject,Hotel {
    @Override
    public void shopping() {
        System.out.println("付款,买到心仪的比基尼");
    }

    @Override
    public void reserve() {
        System.out.println("付预定款,打飞的前往目的地");
    }
}


动态代理 不要手动创建代理类
需要写一个 创建代理类的类

  • 代理对象要执行的方法
    • @param proxy 代理类对象
    • @param method 被代理对象的方法
    • @param args 被代理对象方法的参数
package com.vince.proxy;

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

/**
 * Created by vince on 2017/6/13.
 * 用于动态生成一个代理对象
 */
public class CreateProxy implements InvocationHandler {

    private Object target;//被代理的对象

    //用于创建代理对象的方法
    public Object create(Object target){
        this.target = target;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
        return proxy;
    }

    /**
     * 代理对象要执行的方法
     * @param proxy  代理类对象
     * @param method 被代理对象的方法
     * @param args 被代理对象方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("上海外寻找客户需要的产品...");
        System.out.println("跟客户确认产品");
        method.invoke(target,args);
        System.out.println("完成本次海淘");
        return null;
    }
}


测试一下

package com.vince.proxy;

import org.junit.Test;

/**
 * Created by vince on 2017/6/13.
 */
public class TestDemo {

    @Test
    public void testProxy(){
        CreateProxy cp = new CreateProxy();//用来创建代理对象的对象
        Hotel person = new Person();
        Hotel proxy = (Hotel) cp.create(person);
        //proxy.shopping();//invoke
        proxy.reserve();
    }
}


Java基础之02 动态代理模式172 173 类加载器原理分析
Java基础之02 动态代理模式172 173 类加载器原理分析

类加载器原理分析

1、类的加载过程
JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:
Java基础之02 动态代理模式172 173 类加载器原理分析

  1. 装载:查找并加载类的二进制数据;
    2)链接:
    验证:确保被加载类的正确性;
    准备:为类的静态变量分配内存,并将其初始化为默认值;
    解析:把类中的符号引用转换为直接引用;
    3)初始化:为类的静态变量赋予正确的初始值;

2、类的初始化,类什么时候才被初始化:

1)创建类的实例,也就是new一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName(“com.vince.Dog”))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM启动时标明的启动类,即文件名和类名相同的那个类

3、类的加载:
指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Java.lang.Class对象,用来封装类在方法区类的对象。