JDK動態代理
阿新 • • 發佈:2017-05-20
param ati ide null pop system handler mic cto
上面的類載入器,視頻中推薦是用目標對象的類載入器。
還有,把那個代理類改個名字好點,改成某某工廠類,不然聽著怪難受的。
改成: 測試代碼:
http://rejoy.iteye.com/blog/1627405
這篇文章說的夠具體了。可是對比傳智播客那個視頻。貌似有點問題。
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
上面的類載入器,視頻中推薦是用目標對象的類載入器。
return Proxy.newProxyInstance(target.getClass.getClassLoader().getContextClassLoader(), target.getClass().getInterfaces(), this);
還有,把那個代理類改個名字好點,改成某某工廠類,不然聽著怪難受的。
package dynamic.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 實現自己的InvocationHandler * @author zyb * @since 2012-8-9 * */ public class MyInvocationHandler implements InvocationHandler { // 目標對象 private Object target; /** * 構造方法 * @param target 目標對象 */ public MyInvocationHandler(Object target) { super(); this.target = target; } /** * 運行目標對象的方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在目標對象的方法運行之前簡單的打印一下 System.out.println("------------------before------------------"); // 運行目標對象的方法 Object result = method.invoke(target, args); // 在目標對象的方法運行之後簡單的打印一下 System.out.println("-------------------after------------------"); return result; } /** * 獲取目標對象的代理對象 * @return 代理對象 */ public Object getProxy() { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this); } }
改成:
package cn.itcast.service.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author Administrator * JDK動態代理工廠。依據目標對象生成代理對象 */ public class JDKProxyFactory implements InvocationHandler{ //要代理的對象 private Object targetObject; //負責生成代理對象的工廠方法 public Object createProxyObject(Object object){ //生成PersonServiceBean的代理對象 this.targetObject = object; Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); return null; } //代理對象。在獲知要調用目標對象的方法時,會回調該方法。在該方法中,代理對象要把對目標對象的操作,委派目標對象運行。 /* * 有一臺打印機(目標對象)實現3C標準(接口,沒有質量保證。誰敢用),具有打印功能(方法)。 * 有一個會操作打印機的人(代理對象),店主。 * 如今有人來打印,就叫店主幫他打印。店主知道了客人要求要打印(請求) * 但是店主自己本身不能打印啊(會打印還得了),核對一下打印的文件(打印前), * 僅僅能給打印機輸入打印指令和參數,讓他進行打印(委派目標對象進行處理),收集文件(打印後) * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result ; // TODO Auto-generated method stub System.out.println("目標對象運行方法前"); result = method.invoke(targetObject, args); System.out.println("目標對象運行方法後"); return result; } }
package junit.test; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.itcast.service.PersonService; import cn.itcast.service.impl.JDKProxyFactory; import cn.itcast.service.impl.PersonServiceBean; public class SpringTest { @Test public void jdkProxyTest(){ ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"}); PersonService bean = (PersonServiceBean)ctx.getBean("personService1"); //這裏就不同過容器進行創建PersonService了 JDKProxyFactory jf = new JDKProxyFactory(); //由於代理對象實現了目標對象的全部接口,所以也能夠生產的代理對象也是能夠賦值給PersonSercvice PersonService personService2 = (PersonService) jf.createProxyObject(bean); personService2.save(); } }
JDK動態代理