JDK動態代理與CGLIB動態代理
阿新 • • 發佈:2018-04-02
RR callback arm back 第一個 throw cati proxy clas
一、jdk動態代理 代理目標是 接口實現類的形式
代理的目標對象:
1 public class PersonServiceImpl implements PersonService { 2 private Person person; 3 @Override 4 public void savePerson() { 5 System.out.println("保存用戶"); 6 } 7 public Person getPerson() { 8 return person; 9 } 10 publicvoid setPerson(Person person) { 11 this.person = person; 12 } 13 }
代理:
1 /** 2 * 創建動態代理類,需要實現InvocationHandler接口 3 */ 4 public class JDKProxy implements InvocationHandler{ 5 //指定目標代理對象 6 private Object targetObj; 7 public Object createObjectProxyInstance(Object targetObj){8 this.targetObj = targetObj; 9 /** 10 * 第一個參數:目標對象的類的加載器 11 * 第二個參數:目標對象的接口 12 * 第三個參數:設置回掉對象,當前代理對象的方法被調用時,會委派改參數去調用invoke 13 */ 14 return Proxy.newProxyInstance(this.targetObj.getClass().getClassLoader(), this.targetObj.getClass().getInterfaces(), this); 15 } 16 /** 17 * proxy:代理類 18 * method:要調用的業務方法 19 * args:調用業務方法的參數 20 */ 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 23 //通過反射獲得getPerson方法 24 Method getMeth = this.targetObj.getClass().getMethod("getPerson", null); 25 Object person = getMeth.invoke(targetObj, null); 26 Object obj = null; 27 if(person != null){ 28 obj = method.invoke(targetObj, args); 29 }else{ 30 System.out.println("你沒有登陸"); 31 } 32 return obj; 33 } 34 }
測試:
1 @Test 2 public void test1(){ 3 PersonServiceImpl psi = new PersonServiceImpl(); 4 psi.setPerson(new Person()); 5 PersonService ps = (PersonService) new JDKProxy().createObjectProxyInstance(psi); 6 System.out.println(ps.getClass()); 7 ps.savePerson(); 8 }
二、CGLIB動態代理
可以對普通類實現代理,但該類不能被final修飾,方法也不能被final修飾
代理:
1 public class CGLIBProxy implements MethodInterceptor{ 2 //指定代理目標對象 3 private Object targetObj; 4 public Object creatProxyInstance(Object targetObj){ 5 this.targetObj = targetObj; 6 Enhancer en = new Enhancer(); 7 //設置代理類的父類 8 en.setSuperclass(this.targetObj.getClass()); 9 //設置回掉對象 10 en.setCallback(this); 11 //創建代理類 12 return en.create(); 13 } 14 @Override 15 public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { 16 //通過反射獲得getPerson方法 17 Method tarMeth = this.targetObj.getClass().getMethod("getPerson", null); 18 Person person = (Person) tarMeth.invoke(this.targetObj, null); 19 Object obj = null; 20 if(person != null){ 21 obj = method.invoke(this.targetObj, arg2); 22 }else{ 23 System.out.println("沒有登陸"); 24 } 25 return obj; 26 } 27 }
測試:
1 @Test 2 public void test2(){ 3 PersonServiceImpl psi = new PersonServiceImpl(); 4 psi.setPerson(new Person()); 5 PersonServiceImpl ps = (PersonServiceImpl) new CGLIBProxy().creatProxyInstance(psi); 6 System.out.println(ps.getClass()); 7 ps.savePerson(); 8 }
JDK動態代理與CGLIB動態代理