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();
}
}
类加载器原理分析
1、类的加载过程
JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:
- 装载:查找并加载类的二进制数据;
2)链接:
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;
2、类的初始化,类什么时候才被初始化:
1)创建类的实例,也就是new一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName(“com.vince.Dog”))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM启动时标明的启动类,即文件名和类名相同的那个类
3、类的加载:
指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Java.lang.Class对象,用来封装类在方法区类的对象。