------- android培訓、java培訓、期待與您交流! ----------
接上兩篇技術文檔,對代理模式的最後總結,建議spring框架開發,那麼模擬一個需求如下:
config,peroperties文件如下:
xxx=com.proxy.aopframework.DynamicProxy
#xxx=java.util.ArrayList
xxx.active=com.proxy.aopframework.AdviceAfter
xxx.target=java.util.ArrayList
具體代碼實現及詳細思路,如下:
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、創建通知類
/*
* 創建通知類,在代理中委託類執行前,執行
*
* @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");
}
BeanFactory.bean()
AdviceAfter.AdviceIn()public abstract boolean java.util.List.add(java.lang.Object)
通過以上代碼以及分析,可以更清晰瞭解反射、動態代理,實現AOP思想的Spring框架
-------android培訓、JAVA培訓、期待與您交流! ----------
--------詳細請查看www.itheima.com-------------