类的加载
类加载器:类加载器是负责加载类的对象。将class文件(硬盘)加载到内存生成Class对象。
使用 类.class.getClassLoader() 获得加载自己的类加载器
类加载器加载机制:全盘负责委托机制
全盘负责:A类如果要使用B类(不存在),A类加载器C必须负责加载B类。
委托机制:A类加载器如果要加载资源B,必须询问父类加载是否加载。
如果加载,将直接使用。
如果没有机制,自己再加载。
采用 全盘负责委托机制 保证一个class文件只会被加载一次,形成一个Class对象。
注意:
- 如果一个class文件,被两个类加载器加载,将是两个对象。
- 自定义类加载,可以将一个class文件加载多次。
动态代理
Java代理有JDK动态代理,主要使用的是Java反射机制(即java.lang.reflect包)。
动态代理:程序运行时,使用JDK提供工具类(Proxy),动态创建一个类,此类一般用于代理。
代理:你 – 代理(增强) – 厂商
代理类:
目标类:被代理的
动态代理使用前提:必须有接口
Object proxyObj = Proxy.newProxyInstance(参数1,参数2,参数3);
参数1:ClassLoader,负责将动态创建类,加载到内存。 当前类.class.getClassLoader();
参数2:Class[] interfaces ,代理类需要实现的所有接口(确定方法),被代理类实例.getClass().getInterfaces();
参数3:InvocationHandler, 请求处理类,代理类不具有任何功能,代理类的每一个方法执行时,调用处理类invoke方法。
invoke(Object proxy ,Method method,Object[] args)
参数1:代理实例
参数2:当前执行的方法
参数3:方法实际参数。
public interface UserInter {
public void eat();
public void study();
}
public class UserDaoImpl implements UserInter{
@Override
public void eat() {
System.out.println("正在吃饭");
}
@Override
public void study() {
System.out.println("正在学习");
}
}
public class UserProxyImpl implements UserInter{
private UserDaoImpl imp;
public UserProxyImpl(){}
public UserProxyImpl(UserDaoImpl imp){
this.imp = imp;
}
@Override
public void eat() {
System.out.println("开始吃饭了");
imp.eat();
System.out.println("吃饭结束了");
}
@Override
public void study() {
imp.study();
}
}
public class UserProxyDynamicImpl implements InvocationHandler {
public Object object;
public UserProxyDynamicImpl(Object obj){
this.object = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(object);
//System.out.println(proxy);
//(原本对象)自己调用自己
method.invoke(object, args);
return null;
}
public class ProxyTest {
public static void main(String[] args){
UserDaoImpl imp = new UserDaoImpl();
//静态代理类
UserProxyImpl proxy = new UserProxyImpl(imp);
proxy.eat();
//1.原本类必须要接口
UserDaoImpl user= new UserDaoImpl();
//2.实现代理类的InvocationHandler接口
InvocationHandler ih = new UserProxyDongtaiImpl(user);
//3.动态创建代理类
UserInter proxy = (UserInter) Proxy.newProxyInstance(UserDaoImpl.class.getClassLoader(),
new Class[]{UserInter.class},ih);
proxy.eat();
proxy.study();
}
}