JAVA中的代理可以在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)一組接口的新類,這種功能只有在編譯時(shí)無法確定需要實(shí)現(xiàn)哪個(gè)接口時(shí)才有必要使用,對(duì)于應(yīng)用程序設(shè)計(jì)人員來說,遇到這種情況的機(jī)會(huì)很少。然而對(duì)于系統(tǒng)程序設(shè)計(jì)人員來說,代理帶來的靈活性卻十分重要。??????????????????????????????????????????????????????????? ? ---摘自《JAVA核心技術(shù)卷2》
有一些初學(xué)者對(duì)反射和代理有一點(diǎn)害怕,覺得這是高深的技術(shù),不敢去碰,其實(shí)任何東西都沒有那么復(fù)雜,只要你去接觸,就會(huì)有收獲,這篇文章主要講解了反射和代理、AOP方面的知識(shí),但是非常基本,如果有朋友不太明白可以發(fā)表評(píng)論,我會(huì)認(rèn)真的解答的,下面我貼上兩個(gè)程序的代碼,很簡(jiǎn)單大家看一下。
--------------------------------------------------
/**
?*這個(gè)程序的功能是通過反射技術(shù)得到一個(gè)類(SrcClass)的兩個(gè)String類型的成員變量
?*然后經(jīng)過判斷對(duì)字符串進(jìn)行處理
?*這個(gè)題目的特點(diǎn):通過對(duì)API的閱讀了解Class類的使用方法
?*1、getDeclaredFields()得到所有的成員變量
?*2、Field類中的一些方法getType()
?*3、Field類繼承于AccessibleObject類,有一個(gè)setAccessible()方法,查看API得到他的用途
?**/
import java.lang.reflect.Field;
class SrcClass
{
?private String name = "BeiJing.2008";//定義來兩個(gè)String類型的變量,訪問修飾都是私有的
?private String eMail = "BeiJing.2008@163.com";
?private int age = 25;
?
?
?public String toString()//覆蓋父類的toString方法,打印數(shù)據(jù)
?{
??return "Name:[ " + this.name + " ] EMail: [ " + this.eMail + " ] Age: [ " + this.age + " ]";
?}
}
public class TestClass
{
?public static void main(String[] args)
?{
??SrcClass srcclass = new SrcClass();//首先實(shí)例化一個(gè)SrcClass類的實(shí)例,用于給amendString方法傳值
??TestClass testclass = new TestClass();//再實(shí)力化一個(gè)TestClass的實(shí)例
??
??System.out.println(srcclass);//打印一遍原始信息
??
??testclass.amendString(srcclass);//調(diào)用amendString方法
??System.out.println(srcclass);//打印一遍修改后的信息
?}
?
?
?public void amendString(Object cls)//用于修改通過代理得到srcclass的String成員變量,進(jìn)行替換處理
?{
??try
??{
???Field[] fidles = cls.getClass().getDeclaredFields();//得到srcclass.getClass()類中的所有成員變量
???for(Field field : fidles)//增強(qiáng)for循環(huán)
???{
????if(field.getType().equals(java.lang.String.class))//判斷這個(gè)成員變量的類型是不是String類型的
????{???????????????????????????????????????????????? //如果返回true就進(jìn)行處理
?????field.setAccessible(true);//設(shè)置這個(gè)變量不進(jìn)行訪問權(quán)限檢查(我在SrcClass里設(shè)置的變量為private)
?????String newString = (String)field.get(cls);//通過Field類的get方法得到String成員變量
?????
?????field.set(cls,newString.replaceAll("BeiJing","China"));//進(jìn)行替換,再調(diào)用Field類的set方法進(jìn)行修改
????}
???}
??}
??
??catch(SecurityException e)//
??{
???e.printStackTrace();
??}
??
??catch (IllegalArgumentException e)
??{
???
???e.printStackTrace();
??}
??
??catch (IllegalAccessException e)
??{
???
???e.printStackTrace();
??}
??catch(Exception e)
??{
???e.printStackTrace();
??}
?}
}
------------------------------------------------
下面就是代理了,實(shí)現(xiàn)代理必須有4個(gè)類(一個(gè)接口3各類)
public interface FooInterface {
??? public String printMassage();
}
---------------------------------------------
class ImplementFoo implements FooInterface {
????
????? public String printMassage()
??? {
?????????????? return "This is ImplementFoo ...";
??? }
}
?
---------------------------------------------
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date;
class ImplementInvocationHandler implements InvocationHandler
{
??? private Object foo;
??? public ImplementInvocationHandler(Object foo) //獲得將要運(yùn)行類的實(shí)際對(duì)象
??? {
?????? this.foo = foo;???
??? }
??? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable //
??? {
??????? System.out.println("You want use " + proxy.getClass().getName() + "." +?
??????????????????????????????????????????method.getName() + " at " + new Date());
??????? return?? method.invoke(foo);//方法調(diào)用
??? }
???
}
---------------------------------------------
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
/**
?*?? InvocationHandler handler = new MyInvocationHandler(...);
???? Class proxyClass = Proxy.getProxyClass(
???????? Foo.class.getClassLoader(), new Class[] { Foo.class });
???? Foo f = (Foo) proxyClass.
???????? getConstructor(new Class[] { InvocationHandler.class }).
???????? newInstance(new Object[] { handler });
?*
?*/
public class TestProxy {
???
?
??? public static void main(String[] args)
??? {
??????? ImplementFoo foo = new ImplementFoo();//實(shí)例化一個(gè)實(shí)現(xiàn)了FooInterface(自己定義的)接口的類
??????? InvocationHandler handler = new ImplementInvocationHandler(foo);
??????? //自己編寫實(shí)現(xiàn)InvocationHandler接口的類
??????? //并且將他實(shí)例化,ImplementInvocationHandler類中有一個(gè)構(gòu)造函數(shù)需要接受一個(gè)ImplementFoo類的對(duì)象,? 因?yàn)槲覀儗?br />??????? //要使用ImplementFoo.printMassage方法,ImplementInvocationHandler類方法invoke中的method.invoke(foo)
??????? //需要知道他將調(diào)用誰的printMassage方法,所以我們要給ImplementInvocationHandler類傳遞一個(gè)ImplementFoo類的對(duì)象
???????
???????? Class proxyClass = Proxy.getProxyClass(FooInterface.class.getClassLoader(),FooInterface.class);
??????? //此時(shí)我們就要制造出一個(gè)代理類了,使用Proxy類的靜態(tài)方法getProxyClass,查看API得到答案
???????
????????? FooInterface f;
??????? try
??????? {
??????
??????????? f =? (FooInterface) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(handler);
??????????? System.out.println(f.hashCode());//動(dòng)態(tài)實(shí)例化出一個(gè)代理類,并且調(diào)用他的hashCode、printMassage方法
??????????? System.out.println(f.printMassage());
??????????
??????? } catch (SecurityException ex) {
??????????? ex.printStackTrace();
??????? } catch (IllegalArgumentException ex) {
??????????? ex.printStackTrace();
??????? } catch (IllegalAccessException ex) {
??????????? ex.printStackTrace();
??????? } catch (InstantiationException ex) {
??????????? ex.printStackTrace();
??????? } catch (NoSuchMethodException ex) {
??????????? ex.printStackTrace();
??????? } catch (InvocationTargetException ex) {
??????????? ex.printStackTrace();
??????? }
?
??? }
???
}