代理模式之动态代理
Posted t-mmy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式之动态代理相关的知识,希望对你有一定的参考价值。
代理设计模式:使用代理对象将原始对象包装起来,然后用代理对象取代原始对象。任何对原始对象的调用都要通过代理对象。代理对象决定是否以及何时将方法调用转到原始对象上。
1)接口MathInterface.java:
public interface MathInterface { //加 public int add(int a,int b); //减 public int sub(int a,int b); //乘 public int mul(int a,int b); //除 public int div(int a,int b); } |
2)实现类MathImpl.java:
public class MathImpl implements MathInterface {
@Override public int add(int a, int b) { int result = a + b; return result; }
@Override public int sub(int a, int b) { int result = a - b; return result; }
@Override public int mul(int a, int b) { int result = a * b; return result; }
@Override public int div(int a, int b) { int result = a / b; return result; } } |
3)MathInterfaceLogProxy.java:
/* * 生成MathInterface的代理对象的工厂类: */ public class MathInterfaceLogProxy {
//1>成员变量MathInterface的对象math,要被代理的对象(原始对象) private MathInterface math;
/* * 2>在构造器中将要被代理的对象传给工厂类对象 */ public MathInterfaceLogProxy(MathInterface math){ this.math = math; }
/* * 3>获取代理对象的工厂方法,返回值还是MathInterface类型 */ public MathInterface getMathInterfaceProxy(){ //1)声明一个MathInterface对象,即接收最终生成且要被返回的代理对象 MathInterface proxy = null; //2)获取被代理的对象的类加载器,表示生成的代理对象由哪个类加载负责加载 ClassLoader loader = math.getClass().getClassLoader(); //3)指定生成的代理对象的类型,代理对象就由此可知道所要代理的原始对象中的所有方法 Class[] mathInterfaceClass = new Class[]{MathInterface.class}; //4)匿名内部类,当调用生成的代理对象所代理的原始对象的任何方法时执行的代码 InvocationHandler handler = new InvocationHandler() { /** * invoke方法的参数: * Object proxy:表示代理对象,该对象在invoke方法中一般不使用 * Method method:表示代理对象正在调用的所代理的对象的方法 * Object[] params:表示代理对象正在调用的所代理的对象的方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
//代理对象正在调用的方法名 String methdoName = method.getName(); //执行前的日志 System.out.println("日志: The method "+methdoName+" begin with "+Arrays.toString(params)); //执行方法 int result = (int) method.invoke(math, params); //执行后的日志 System.out.println("日志: The method "+methdoName+" end with "+result);
return result; } };
/* * 5)实例化代理对象: * 调用java.lang.reflect.Proxy类的静态方法newProxyInstance() * 参数一ClassLoader:生成代理对象使用的类加载器 * 参数二Class[]:指定生成的代理对象的类型 * 参数三InvocationHandler:指定当具体调用生成的代理对象所代理的对象的方法时执行的内容。 * 本质是调用了参数InvocationHandler对象的invoke()方法 */ proxy = (MathInterface) Proxy.newProxyInstance(loader, mathInterfaceClass, handler);
//6)返回生成的代理对象 return proxy; } } |
4)测试:
package com.mmy.aop.helloworld;
public class Test {
public static void main(String[] args) {
//1.创建方法中没有日志代码的MathInterface实现类MathImpl对象(被代理的对象) MathInterface math = new MathImpl(); //2.创建生成MathInterface的代理对象的工厂类对象,并传入被代理的对象 MathInterfaceLogProxy factory = new MathInterfaceLogProxy(math); //3.调用工厂类对象的工厂方法,生成MathInterface的代理对象 MathInterface proxy = factory.getMathInterfaceProxy(); //4.测试 /* * 日志:The method add begin with [2,3] 日志:The method add end with 5 5 */ int result = proxy.add(2, 3); System.out.println(result); /* * 日志:The method mul begin with [4,5] 日志:The method mul end with 20 20 */ result = proxy.mul(4, 5); System.out.println(result); } } |
以上是关于代理模式之动态代理的主要内容,如果未能解决你的问题,请参考以下文章