代理模式總結-仿製簡單spring框架

------- android培訓java培訓、期待與您交流! ----------

接上兩篇技術文檔,對代理模式的最後總結,建議spring框架開發,那麼模擬一個需求如下:

 * 需求:以動態代理和反射方式實現Spring中AOP面向切面編程思想
 * 在config.properties配置文件中進行配置,實現程序讀取哪些類進行運行
 * 比如,讀取的xxx是com.proxy.aopframework.DynamicProxy,則以代理類執行,並且如果是代理類執行,
 * 則會讀取active和target,target爲委託類,active爲日誌類,如果配置AdviceAfter,
 * 則在委託類執行後記錄日誌,否則在之前記錄日誌.

config,peroperties文件如下:

xxx=com.proxy.aopframework.DynamicProxy
#xxx=java.util.ArrayList
xxx.active=com.proxy.aopframework.AdviceAfter
xxx.target=java.util.ArrayList


 * 思路:
 * 
 * 1、將config.properties讀進來,根據讀進來的ID和值,使用Properties類進行load存儲
 * 2、創建代理類。對Properties中的值進行判斷,是否使用代理類


具體代碼實現及詳細思路,如下:

1、通知接口類

package com.proxy.aopframework;


import java.lang.reflect.Method;
/*
 * 創建通知接口,經過分析,由於在代理中,委託類執行前,執行後,
 * 都需要有通知功能,通知屬於同一類型,那麼封裝成一個接口,供其他程序實現使用
 * 
 *  @author lijl
 * */
public interface AdviceInterface {
public void AdviceIn(Object reflect, Method method, Object[] arg);


}

------------------------------------------------------華麗麗的分割線——-------------------------------------------------------------------------


2、創建通知類


import java.lang.reflect.Method;
/*
 * 創建通知類,在代理中委託類執行前,執行
 * 
 *  @author lijl
 * */
public class AdviceBefore implements AdviceInterface{


@Override
public void AdviceIn(Object reflect, Method method, Object[] arg) {
// TODO Auto-generated method stub
System.out.println("AdviceBefore.AdviceIn()"+method);
}


}

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

package com.proxy.aopframework;


import java.lang.reflect.Method;
/*
 * 創建通知類,在代理中委託類執行後,執行
 * 
 *  @author lijl
 * */
public class AdviceAfter implements AdviceInterface{


@Override
public void AdviceIn(Object reflect, Method method, Object[] arg) {
// TODO Auto-generated method stub
System.out.println("AdviceAfter.AdviceIn()"+method);
}


}


-----------------------------------------------------------------------華麗麗的分割線----------------------------------------------------------------------------------------------------------------

3、代理類


package com.proxy.aopframework;
import java.lang.reflect.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/*
 *  創建代理類
 * 1、實現InvocationHandler接口
 * 2、實例化對象後,將委託類對象傳遞進來,使用setProxy方法
 * 3、在傳遞進來的同時,返回委託類的動態代理對象,使用Proxy的newProxyInstance方法,
 * pro.getClass().getClassLoader()  傳遞委託類的加載器,
 * pro.getClass().getInterfaces()   委託類的接口,
 * this                             本代理類的對象
 * 
 * 4、代理類DynamicProxy重寫invoke方法,public Object invoke(Object proxy, Method method, Object[] args)
 * 5、在invoke方法中,使用反射技術,對委託類進行操作,在委託類執行前,記錄日誌通知,委託類執行後,記錄日誌通知
 * 6、對5進行詳解,外界對AdviceInterface進行設置對象,使用set方法,如果不同的傳值,執行不同的日誌通知
 * 
 *  @author lijl
 * */
public class DynamicProxy implements InvocationHandler {
private Object pro;


AdviceInterface befor;
AdviceInterface after;
public Object setProxy(Object pro){
this.pro = pro;

Object obj = Proxy.newProxyInstance(pro.getClass().getClassLoader(), 
pro.getClass().getInterfaces(), this);
return obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(befor != null)
befor.AdviceIn(proxy, method, args);

Object object = method.invoke(pro, args);

if(after != null)
after.AdviceIn(proxy, method, args);
return object;
}

public void setBefor(AdviceInterface befor) {
this.befor = befor;
}


public void setAfter(AdviceInterface after) {
this.after = after;
}

}


-----------------------------------------------------------------------華麗麗的分割線----------------------------------------------------------------------------------------------------------------

4、工廠類


package com.proxy.aopframework;


import java.io.*;
import java.util.*;
/*
 *  創建bean工廠類
1、使用IO技術讀取配置文件config.properties,將讀取的信息load到Properties鍵值對裏
2、將Properties中的數據通過getProperty取出
3、通過反射技術,將取出來的類名進行實例化對象
4、對實例化的對象進行判斷,如果配置信息的bean屬於代理類DynamicProxy的類型,則繼續取出active,target,將兩個類實例化對象
5、將target目標類對象,通過代理類DynamicProxy的setProxy方法進行傳值,返回Object類型對象,將該對象返回。
同時在中間進行判斷,如果active通知類的對象與AdviceBefore(委託類執行前,執行通知類)相同,則執行setBefor方法
否則執行setAfter方法
6、如果bean不屬於DynamicProxy類,則返回bean,不進行代理
 *  @author lijl
 * */
public class BeanFactory {
private Properties pt = new Properties();
public void bean() throws Exception{
FileReader fr = new FileReader("E:\\Workspaces\\MyEclipse Professional 2014\\exam\\src\\com\\proxy\\aopframework\\config.properties");
pt.load(fr);
System.out.println("BeanFactory.bean()");
}
public Object factory() throws Exception{
String name = pt.getProperty("xxx");
Class clazz = Class.forName(name);
Object bean = clazz.newInstance();
if(bean instanceof DynamicProxy){
String active = pt.getProperty("xxx.active");
String target = pt.getProperty("xxx.target");
Object clazz_target = Class.forName(target).newInstance();
Object clazz_active = Class.forName(active).newInstance();
Object dp =((DynamicProxy)bean).setProxy(clazz_target);
if(clazz_active instanceof AdviceBefore)
((DynamicProxy) bean).setBefor((AdviceInterface)clazz_active);
else if(clazz_active instanceof AdviceAfter)
((DynamicProxy) bean).setAfter((AdviceInterface)clazz_active);


return dp;
}
return bean;
}

}

-----------------------------------------------------------------------華麗麗的分割線----------------------------------------------------------------------------------------------------------------

5、主函數

public class test_main {
public static void main(String[] args) throws Exception{
BeanFactory e  = new BeanFactory();
e.bean();
Object sl = e.factory();
((List) sl).add("kkk");
}


6、結果:

BeanFactory.bean()
AdviceAfter.AdviceIn()public abstract boolean java.util.List.add(java.lang.Object)

通過以上代碼以及分析,可以更清晰瞭解反射、動態代理,實現AOP思想的Spring框架

 -------android培訓JAVA培訓、期待與您交流! ----------

--------詳細請查看www.itheima.com-------------


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