关于jdk代理与cglib代理
Posted 爱喝啤酒的猴子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于jdk代理与cglib代理相关的知识,希望对你有一定的参考价值。
尊重原创
原文地址:点击打开链接
一、为什么需要代理模式
假设需实现一个计算的类Math、完成加、减、乘、除功能,如下所示:
1 package com.zhangguo.Spring041.aop01; 2 3 public class Math 4 //加 5 public int add(int n1,int n2) 6 int result=n1+n2; 7 System.out.println(n1+"+"+n2+"="+result); 8 return result; 9 10 11 12 //减 13 public int sub(int n1,int n2) 14 int result=n1-n2; 15 System.out.println(n1+"-"+n2+"="+result); 16 return result; 17 18 19 //乘 20 public int mut(int n1,int n2) 21 int result=n1*n2; 22 System.out.println(n1+"X"+n2+"="+result); 23 return result; 24 25 26 //除 27 public int div(int n1,int n2) 28 int result=n1/n2; 29 System.out.println(n1+"/"+n2+"="+result); 30 return result; 31 32
现在需求发生了变化,要求项目中所有的类在执行方法时输出执行耗时。最直接的办法是修改源代码,如下所示:
1 package com.zhangguo.Spring041.aop01; 2 3 import java.util.Random; 4 5 public class Math 6 //加 7 public int add(int n1,int n2) 8 //开始时间 9 long start=System.currentTimeMillis(); 10 lazy(); 11 int result=n1+n2; 12 System.out.println(n1+"+"+n2+"="+result); 13 Long span= System.currentTimeMillis()-start; 14 System.out.println("共用时:"+span); 15 return result; 16 17 18 //减 19 public int sub(int n1,int n2) 20 //开始时间 21 long start=System.currentTimeMillis(); 22 lazy(); 23 int result=n1-n2; 24 System.out.println(n1+"-"+n2+"="+result); 25 Long span= System.currentTimeMillis()-start; 26 System.out.println("共用时:"+span); 27 return result; 28 29 30 //乘 31 public int mut(int n1,int n2) 32 //开始时间 33 long start=System.currentTimeMillis(); 34 lazy(); 35 int result=n1*n2; 36 System.out.println(n1+"X"+n2+"="+result); 37 Long span= System.currentTimeMillis()-start; 38 System.out.println("共用时:"+span); 39 return result; 40 41 42 //除 43 public int div(int n1,int n2) 44 //开始时间 45 long start=System.currentTimeMillis(); 46 lazy(); 47 int result=n1/n2; 48 System.out.println(n1+"/"+n2+"="+result); 49 Long span= System.currentTimeMillis()-start; 50 System.out.println("共用时:"+span); 51 return result; 52 53 54 //模拟延时 55 public void lazy() 56 57 try 58 int n=(int)new Random().nextInt(500); 59 Thread.sleep(n); 60 catch (InterruptedException e) 61 e.printStackTrace(); 62 63 64
测试运行:
package com.zhangguo.Spring041.aop01; public class Test @org.junit.Test public void test01() Math math=new Math(); int n1=100,n2=5; math.add(n1, n2); math.sub(n1, n2); math.mut(n1, n2); math.div(n1, n2);
运行结果:
缺点:
1、工作量特别大,如果项目中有多个类,多个方法,则要修改多次。
2、违背了设计原则:开闭原则(OCP),对扩展开放,对修改关闭,而为了增加功能把每个方法都修改了,也不便于维护。
3、违背了设计原则:单一职责(SRP),每个方法除了要完成自己本身的功能,还要计算耗时、延时;每一个方法引起它变化的原因就有多种。
4、违背了设计原则:依赖倒转(DIP),抽象不应该依赖细节,两者都应该依赖抽象。而在Test类中,Test与Math都是细节。
使用静态代理可以解决部分问题。
二、静态代理
1、定义抽象主题接口。
package com.zhangguo.Spring041.aop02; /** * 接口 * 抽象主题 */ public interface IMath //加 int add(int n1, int n2); //减 int sub(int n1, int n2); //乘 int mut(int n1, int n2); //除 int div(int n1, int n2);
2、主题类,算术类,实现抽象接口。
package com.zhangguo.Spring041.aop02; /** * 被代理的目标对象 *真实主题 */ public class Math implements IMath //加 public int add(int n1,int n2) int result=n1+n2; System.out.println(n1+"+"+n2+"="+result); return result; //减 public int sub(int n1,int n2) int result=n1-n2; System.out.println(n1+"-"+n2+"="+result); return result; //乘 public int mut(int n1,int n2) int result=n1*n2; System.out.println(n1+"X"+n2+"="+result); return result; //除 public int div(int n1,int n2) int result=n1/n2; System.out.println(n1+"/"+n2+"="+result); return result;
3、代理类
1 package com.zhangguo.Spring041.aop02; 2 3 import java.util.Random; 4 5 /** 6 * 静态代理类 7 */ 8 public class MathProxy implements IMath 9 10 //被代理的对象 11 IMath math=new Math(); 12 13 //加 14 public int add(int n1, int n2) 15 //开始时间 16 long start=System.currentTimeMillis(); 17 lazy(); 18 int result=math.add(n1, n2); 19 Long span= System.currentTimeMillis()-start; 20 System.out.println("共用时:"+span); 21 return result; 22 23 24 //减法 25 public int sub(int n1, int n2) 26 //开始时间 27 long start=System.currentTimeMillis(); 28 lazy(); 29 int result=math.sub(n1, n2); 30 Long span= System.currentTimeMillis()-start; 31 System.out.println("共用时:"+span); 32 return result; 33 34 35 //乘 36 public int mut(int n1, int n2) 37 //开始时间 38 long start=System.currentTimeMillis(); 39 lazy(); 40 int result=math.mut(n1, n2); 41 Long span= System.currentTimeMillis()-start; 42 System.out.println("共用时:"+span); 43 return result; 44 45 46 //除 47 public int div(int n1, int n2) 48 //开始时间 49 long start=System.currentTimeMillis(); 50 lazy(); 51 int result=math.div(n1, n2); 52 Long span= System.currentTimeMillis()-start; 53 System.out.println("共用时:"+span); 54 return result; 55 56 57 //模拟延时 58 public void lazy() 59 60 try 61 int n=(int)new Random().nextInt(500); 62 Thread.sleep(n); 63 catch (InterruptedException e) 64 e.printStackTrace(); 65 66 67
4、测试运行
1 package com.zhangguo.Spring041.aop02; 2 3 public class Test 4 5 IMath math=new MathProxy(); 6 @org.junit.Test 7 public void test01() 8 9 int n1=100,n2=5; 10以上是关于关于jdk代理与cglib代理的主要内容,如果未能解决你的问题,请参考以下文章