類的加載
類加載器:類加載器是負責加載類的對象。將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();
}
}