JAVA的動態代理,在MYBATIS中應用的很廣,其核心就是寫一個interface,但不寫實現類,然后用動態代理來實例化並執行這個interface中的方法,話不多說,來看一個實現的例子:
1.先定義一個接口:
public interface TestProxy { String hello(); }
2.雖然不寫實現類,但我們仍然希望在執行這個hello()方法時,能輸出我們想要輸出的內容,比如我把希望要輸出的內容放在一個屬性文件中:
hello=world
我希望在調用hello方法時,輸出world,接下來得解析這個屬性文件:
public class PropertiesHandler { private static Properties p = new Properties(); static{ try { InputStream in = new FileInputStream(new File("src/test.properties")); p.load(in); in.close(); } catch (IOException e) { throw new RuntimeException("test.properties load error!"); } } public static String getProperty(String key){ try{ return p.getProperty(key, null); }catch(Exception e){ e.printStackTrace(); } return ""; } }
3.解析完后,我們再寫一個動態代理類:
public class ProxyImp<T> implements InvocationHandler{ private Class<T> proxyMethod; public ProxyImp(Class<T> proxyMethod) { this.proxyMethod = proxyMethod; } @Override public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { String value = PropertiesHandler.getProperty(method.getName()); System.out.println(value); return null; } }
其原理就是在調用接口類方法時,動態代理類都會去執行這個invoke方法,以達到執行的目的,可以看到,在invoke方法里,我們把hello方法在屬性文件中對應的值給取出來了,並輸出。
4.接下來就是再封裝一個代理工廠類來產生這個接口的一個實例:
public class ProxyImpFactory{ @SuppressWarnings("unchecked") public static <T> T newInstance(Class<T> methodInterface) { final ProxyImp<T> proxyImp = new ProxyImp<T>(methodInterface); return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{methodInterface}, proxyImp); } }
可以從上面的代碼中看出這個代理類會自動的生成一個接口實現類的實例。
5.接下來就是真正的調用了:
public static void main(String[] args) { TestProxy tp = ProxyImpFactory.newInstance(TestProxy.class); tp.hello(); }
輸出就是:world.
6.動態代理在自動化中的作用:
自動化中,當把元素對象用外部文件,把數據文件用外部文件時,都可以用這種方式來進行封裝,其在自動化測試中最大的作用,我想就是利用在封裝關鍵字上了,把關鍵字與具體的方法對應起來,就可以用這樣的方式。
至於具體的關鍵字的實現,我想得靠大家自已了,有興趣的可以與我討論!