由微見著!模擬JDK動態代理的實現2---Spring AOP

續:


/**
 * 測試端
 * @author Administrator
 *
 */
public class Client {
public static void main(String[] args) throws Exception {
UserMgr mgr = new UserMgrImpl();
InvocationHandler h = new TransactionHandler(mgr);
//TimeHandler h2 = new TimeHandler(h);
UserMgr u = (UserMgr)Proxy.newProxyInstance(UserMgr.class,h);
u.addUser();
}
}


-----------------------------------------------------------------------------------------------------------------------

public class TransactionHandler implements InvocationHandler {

private Object target;

public TransactionHandler(Object target) {
super();
this.target = target;
}


@Override
public void invoke(Object o, Method m) {
System.out.println("Transaction Start");
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Transaction Commit");
}


}


-----------------------------------------------------------------------------------------------------------------------

public interface UserMgr {
void addUser();
}

-----------------------------------------------------------------------------------------------------------------------

public class UserMgrImpl implements UserMgr {


@Override
public void addUser() {
System.out.println("1: 插入記錄到user表");
System.out.println("2: 做日誌在另外一張表");
}

}


-----------------------------------------------------------------------------------------------------------------------

/**
 * 定義將要實現的中間代理類的統一接口
 * @author Rick
 *
 */
public interface InvocationHandler {
public void invoke(Object o, Method m);
}



-----------------------------------------------------------------------------------------------------------------------

public interface Moveable {
void move();

}


-----------------------------------------------------------------------------------------------------------------------


/**
 * 實現任意接口的類的代理-使用聚合代理
 * 代理模式有聚合代理和實現繼承的代理
 * 繼承的方式的缺點就是:n級代理就需要n級繼承關係
 * @author Rick
 *
 */
public class Proxy {
public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception { //JDK6 Complier API, CGLib, ASM
String methodStr = "";
String rt = "\r\n";

Method[] methods = infce.getMethods();
/*
for(Method m : methods) {
methodStr += "@Override" + rt + 
"public void " + m.getName() + "() {" + rt +
"   long start = System.currentTimeMillis();" + rt +
"   System.out.println(\"starttime:\" + start);" + rt +
"   t." + m.getName() + "();" + rt +
"   long end = System.currentTimeMillis();" + rt +
"   System.out.println(\"time:\" + (end-start));" + rt +
"}";
}
*/
for(Method m : methods) {
methodStr += "@Override" + rt + 
"public void " + m.getName() + "() {" + rt +
"    try {" + rt +
"    Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
"    h.invoke(this, md);" + rt +
"    }catch(Exception e) {e.printStackTrace();}" + rt +

"}";
}

String src = 
"package com.tamao.dynamicAgent2.proxy;" +  rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements " + infce.getName() + "{" + rt +
"    public $Proxy1(InvocationHandler h) {" + rt +
"        this.h = h;" + rt +
"    }" + rt +


"    com.tamao.dynamicAgent2.proxy.InvocationHandler h;" + rt +

methodStr +
"}";
String fileName = 
"d:/src/com/tamao/dynamicAgent2/proxy/$Proxy1.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);
fw.flush();
fw.close();

//compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(fileName);
CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();

//load into memory and create an instance
//加載到內存並生成一個實例--同樣適用於網絡load來的類
URL[] urls = new URL[] {new URL("file:/" + "d:/src/")};
URLClassLoader ul = new URLClassLoader(urls);
Class c = ul.loadClass("com.tamao.dynamicAgent2.proxy.$Proxy1");
System.out.println(c);

/**
* 站在JVM的角度,拿到類的構造方法的對象(PS:找到方法是根據參數來決定的)
*/

//找到參數類型是Moveable的參數類型的構造方法
Constructor ctr = c.getConstructor(InvocationHandler.class);
Object m = ctr.newInstance(h);
//m.move();


return m;
}
}


-----------------------------------------------------------------------------------------------------------------------

/**
 * 使用聚合來實現代理-代理和被代理也是實現Moveable(自定義Interface)
 * 本類是模擬代理的測試端
 * @author Rick
 *
 */


/**
 * 中間代理類/設定了被代理類爲Object
 * @author Rick
 *
 */
public class TimeHandler implements InvocationHandler{

private Object target;






public TimeHandler(Object target) {
super();
this.target = target;
}


/**
* 定義代理邏輯
*/
@Override
public void invoke(Object o, Method m) {
long start = System.currentTimeMillis();
System.out.println("starttime:" + start);
System.out.println(o.getClass().getName());
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("time:" + (end-start));
}


}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章