一、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 public void 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 }