JDK动态代理与CGLIB动态代理

Posted cat_fish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK动态代理与CGLIB动态代理相关的知识,希望对你有一定的参考价值。

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

 

以上是关于JDK动态代理与CGLIB动态代理的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理与CGLIB动态代理

JDK动态代理与CGLIB动态代理

JDK 动态代理与 CGLIB 动态代理,它俩真的不一样

JDK的动态代理与cglib动态代理

DK动态代理与CGLib动态代理的区别

Spring AOP JDK动态代理与CGLib动态代理区别