Java代理模式
Posted 1234ztc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java代理模式相关的知识,希望对你有一定的参考价值。
关于代理模式的概念:
用现在相当热门的宝强马蓉事件做比喻,宝强相当于是被代理类,宋喆就是代理类,宋喆代理着宝强的许多行为,宋喆对宝强的消息进行预处理、过滤、转发、公关等。就如公关,当宝强需要公关的时候宝强无须真正亲自去实现公关,真正实现的是由宋喆代理完成。
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类 与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
首先我们使用代码来讲解静态代理:
以下是IStar类型接口,也就是明星该有的行为:
1 public interface IStar{ 2 //努力工作 3 void hardWork; 4 //爱妻子 5 void loveWife; 6 }
以下是IStar接口的实现类Satr
public class Star implementsIStar{ private String mName; public Star(String mName){ mName=this.mName; } public void hardWork(){ System.out.printf(this.mName+"努力工作"); } public void loveWife(){ System.out.printf(this.mName+"爱护妻子"); } }
经纪人代表的是明星,所以从某种意义上讲与明星具有相同的行为
public class Agent implements IStar{ //需要代理的对象 IStar mIStar; //代理类的一个成员变量 boolean mIsHappy; public Agent(IStar IStar){ mIStar=IStar; } public Agent(IStar IStar,boolean isHappy){ mIStar=IStar; mIsHappy=isHappy; } //与被代理类具有相同方法 public void hardWork(){ mIStar.hardWork; } //此时代理类也可以改变被代理类的行为方法 public void loveWife(){ if(mIsHappy){ mIStar.loveWife; }else{ System.out.printf("经纪人造反"); } } }
测试类
public class test{ public static void main(String[] args){ //在此新建一个被代理对象 是明星王宝强 Star baoqiang=new Star("王宝强"); //告诉经纪人 他需要代理的对象是明星王宝强 并且将经济人IsHappy属性设 // 为false Agent songjj =new Agent(baoqiang,false); songjj.hardWrok(); songjj.loveWife(); } }
输出结果:王宝强努力工作
经纪人造反
以上是静态代理的例子,有助于代码的解耦。
接下来是动态代理模式:
要求如下:使用java代码完成整数加减乘除算法器,并且
1、在程序执行期间追踪正在发生的活动
2、希望计算器只能处理正数的运算
为了是的代码的集中与不混了我们使用动态代理模式实现
首先是创建一个接口
1 public interface ArithmeticCalculator { 2 3 int add(int i, int j); 4 int sub(int i, int j); 5 6 int mul(int i, int j); 7 int div(int i, int j); 8 9 }
其次是实现ArithmeticCalculator接口
public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } }
穿件代理类ArithmeticCalculatorLoggingProxy
1 1 package com.atguigu.spring.aop; 2 2 3 3 import java.lang.reflect.InvocationHandler; 4 4 import java.lang.reflect.Method; 5 5 import java.lang.reflect.Proxy; 6 6 import java.util.Arrays; 7 7 8 8 public class ArithmeticCalculatorLoggingProxy { 9 9 10 10 //要代理的对象 11 11 private ArithmeticCalculator target; 12 12 13 13 public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { 14 14 super(); 15 15 this.target = target; 16 16 } 17 17 18 18 //返回代理对象 19 19 public ArithmeticCalculator getLoggingProxy(){ 20 20 ArithmeticCalculator proxy = null; 21 21 //获取要代理对象的加载器 22 22 ClassLoader loader = target.getClass().getClassLoader(); 23 23 Class [] interfaces = new Class[]{ArithmeticCalculator.class}; 24 25 24 InvocationHandler h = new InvocationHandler() { 26 25 /** 27 26 * proxy: 代理对象。 一般不使用该对象 28 27 * method: 正在被调用的方法 29 28 * args: 调用方法传入的参数 30 29 */ 31 30 @Override 32 31 public Object invoke(Object proxy, Method method, Object[] args) 33 32 throws Throwable { 34 33 String methodName = method.getName(); 35 34 //打印日志 36 35 System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args)); 37 36 38 37 //调用目标方法 39 38 Object result = null; 40 39 41 40 try { 42 41 //前置通知 43 42 result = method.invoke(target, args); 44 43 //返回通知, 可以访问到方法的返回值 45 44 } catch (NullPointerException e) { 46 45 e.printStackTrace(); 47 46 //异常通知, 可以访问到方法出现的异常 48 47 } 49 48 50 49 //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值 51 50 52 51 //打印日志 53 52 System.out.println("[after] The method ends with " + result); 54 53 55 54 return result; 56 55 } 57 56 }; 58 57 59 58 /** 60 59 * loader: 代理对象使用的类加载器。 61 60 * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法. 62 61 * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法 63 62 */ 64 63 proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); 65 64 66 65 return proxy; 67 66 } 68 67 }
测试类
1 package com.atguigu.spring.aop; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl(); 10 11 arithmeticCalculator = 12 new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy(); 13 14 int result = arithmeticCalculator.add(11, 12); 15 System.out.println("result:" + result); 16 17 result = arithmeticCalculator.div(21, 3); 18 System.out.println("result:" + result); 19 20 } 21 22 }
以上是关于Java代理模式的主要内容,如果未能解决你的问题,请参考以下文章