JDK动态代理(add方法的/所实现的接口中的方法的执行过程 )

创建接口

public interface ICalculatorService {

	int add(int a,int b);	
	int sub(int a,int b);	
	int mul(int a,int b);	
	int div(int a,int b);
}

创建接口实现类,实现加减乘除

public class CalculatorService implements ICalculatorService {

	@Override
	public int add(int a, int b) {
		System.out.println(this.getClass().getName()+":The add method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the add method: ["+a+","+b+"]");
		int result = a+b;
		System.out.println(this.getClass().getName()+":Result of the add method:"+result);
		System.out.println(this.getClass().getName()+":The add method ends.");
		return result;
	}

	@Override
	public int sub(int a, int b) {
		System.out.println(this.getClass().getName()+":The sub method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the sub method: ["+a+","+b+"]");
		int result = a-b;
		System.out.println(this.getClass().getName()+":Result of the sub method:"+result);
		System.out.println(this.getClass().getName()+":The sub method ends.");
		return result;
	}

	@Override
	public int mul(int a, int b) {
		System.out.println(this.getClass().getName()+":The mul method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the mul method: ["+a+","+b+"]");
		int result = a*b;
		System.out.println(this.getClass().getName()+":Result of the mul method:"+result);
		System.out.println(this.getClass().getName()+":The mul method ends.");
		return result;
	}

	@Override
	public int div(int a, int b) {
		System.out.println(this.getClass().getName()+":The div method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the div method: ["+a+","+b+"]");
		int result = a/b;
		System.out.println(this.getClass().getName()+":Result of the div method:"+result);
		System.out.println(this.getClass().getName()+":The div method ends.");
		return result;
	}
}

然后创建类去调用实现类中的方法,就会发现

@Override
	public int add(int a, int b) {
		System.out.println(this.getClass().getName()+":The add method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the add method: ["+a+","+b+"]");
		int result = a+b;
		System.out.println(this.getClass().getName()+":Result of the add method:"+result);
		System.out.println(this.getClass().getName()+":The add method ends.");
		return result;
	}

我每次要使用实现类中的方法时,都要写这么长的代码,而且代码中是有重复的部分,那么是否可以通过某种方式来实现代码的复用,在此引入动态代理的概念

public class Test {
	public static void main(String[] args) {
		//一、创建需要被代理的对象
		ICalculator calculator = new Calculator();
		InvocationHandler handler = new InvocationHandler() {
			@Override
			//三、代理类对象对应方法具体执行内容
			//该方法一共三个参数
			//第一个参数是calculator的代理对象
			//第二个参数是被代理类的方法的对象
			//第三个参数是上面方法对应的参数列表
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println(calculator.getClass().getName()+":The "+method.getName()+" method begins.");
				System.out.println(calculator.getClass().getName()+":Parameters of the "+method.getName()+" method: ["+args[0]+","+args[1]+"]");
				Object result = method.invoke(calculator, args);
				System.out.println(calculator.getClass().getName()+":Result of the "+method.getName()+" method:"+result);
				System.out.println(calculator.getClass().getName()+":The "+method.getName()+" method ends.");
				return result;
			}
		};
		//二、创建代理对象调用Proxy中的静态方法,创建一个被代理的类实现的接口的一个实现类
		//该方法需要传入三个参数分别为
		//1.被代理类的类加载器
		//2.被代理实现的接口
		//3.代理类需要执行的相关方法
		ICalculatorService calculatorProxy = (ICalculatorService) Proxy.newProxyInstance(calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(), handler);
		int result = calculatorProxy.add(3, 5);
		//calculatorProxy存档的是由Proxy创建的实现了接口的一个匿名内部类
		//又因为同样实现接口,所以上文对象可以向下转型
		//调用的add方法时内部类中的add()方法
		//上文中的我们自己写的匿名内部类只是告诉程序要做什么工作
		System.out.println(result);
	}
}

控制台输出

com.replace.dai.CalculatorService:The add method begins.
com.replace.dai.CalculatorService:Parameters of the add method: [10,5]
com.replace.dai.CalculatorService:Result of the add method:15
com.replace.dai.CalculatorService:The add method ends.
15

其中的add方法执行过程为

创建被代理类的对象
创建代理类对象,该类是一个实现了被代理类接口的实现类
把代理对象的类加载器和接口对象传入,最后一个参数为代理类需要执行的方法具体内容
通过InvocationHandler接口创建一个匿名内部类对象并重写invoke方法
该方法三个参数分别为1.代理类对象 2.被代理类的方法对象 3. 被代理类的方法参数
最后执行代理对象的方法,并返回结果

反编译
在主方法的第一行添加

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//反编译器

执行,刷新项目
对生成的.class文件进行反编译

得到匿名内部类


//实现了ICalculatoServicer接口
public final class $Proxy0 extends Proxy
    implements ICalculatorService
{

    public $Proxy0(InvocationHandler invocationhandler)
    {
        super(invocationhandler);
    }

    public final boolean equals(Object obj)
    {
        try
        {
            return ((Boolean)super.h.invoke(this, m1, new Object[] {
                obj
            })).booleanValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final String toString()
    {
        try
        {
            return (String)super.h.invoke(this, m2, null);
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int mul(int i, int j)
    {
        try
        {
            return ((Integer)super.h.invoke(this, m5, new Object[] {
                Integer.valueOf(i), Integer.valueOf(j)
            })).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }
  //生成的add方法
    public final int add(int i, int j)
    {
        try
        {
        	//执行h就是传入的handler匿名内部类对象的重写的invoke方法
            return ((Integer)super.h.invoke(this, m3, new Object[] {
                Integer.valueOf(i), Integer.valueOf(j)
            })).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int sub(int i, int j)
    {
        try
        {
            return ((Integer)super.h.invoke(this, m4, new Object[] {
                Integer.valueOf(i), Integer.valueOf(j)
            })).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int div(int i, int j)
    {
        try
        {
            return ((Integer)super.h.invoke(this, m6, new Object[] {
                Integer.valueOf(i), Integer.valueOf(j)
            })).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int hashCode()
    {
        try
        {
            return ((Integer)super.h.invoke(this, m0, null)).intValue();
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    private static Method m1;
    private static Method m2;
    private static Method m5;
    //m3为add方法对应的Method对象
    private static Method m3;
    private static Method m4;
    private static Method m6;
    private static Method m0;

    static 
    {
        try
        {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
                Class.forName("java.lang.Object")
            });
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m5 = Class.forName("com.replace.dai.ICalculatorService").getMethod("mul", new Class[] {
                Integer.TYPE, Integer.TYPE
            });
            m3 = Class.forName("com.replace.dai.ICalculatorService").getMethod("add", new Class[] {
                Integer.TYPE, Integer.TYPE
            });
            m4 = Class.forName("com.replace.dai.ICalculatorService").getMethod("sub", new Class[] {
                Integer.TYPE, Integer.TYPE
            });
            m6 = Class.forName("com.replace.dai.ICalculatorService").getMethod("div", new Class[] {
                Integer.TYPE, Integer.TYPE
            });
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        }
        catch(NoSuchMethodException nosuchmethodexception)
        {
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }
}


对代理类进行优化

public class ProxyFactory {
	static CalculatorService target ;
	
	InvocationHandler handler =	new InvocationHandler() {
		@Override
		public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable {
			System.out.println(target.getClass().getName()+":The "+method.getName()+" method begins.");
			System.out.println(target.getClass().getName()+":Parameters of the "+method.getName()+" method: ["+parameters[0]+","+parameters[1]+"]");
			Object result = method.invoke(target, parameters);
			System.out.println(target.getClass().getName()+":Result of the "+method.getName()+" method:"+result);
			System.out.println(target.getClass().getName()+":The "+method.getName()+" method ends.");
			return result;
		}
	};
	
	public Object getProxy(CalculatorService target) {
		ProxyFactory.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
	}
}

测试类

public class TestProxy {
	public static void main(String[] args) {
		ProxyFactory factory = new ProxyFactory();
		CalculatorService calculator = new CalculatorService();
		ICalculatorService proxy = (ICalculatorService) factory.getProxy(calculator);
		int result = proxy.add(3, 2);
		System.out.println(result);
	}
}

执行

com.replace.dai.CalculatorService:The add method begins.
com.replace.dai.CalculatorService:Parameters of the add method: [3,2]
com.replace.dai.CalculatorService:The add method begins.
com.replace.dai.CalculatorService:Parameters of the add method: [3,2]
com.replace.dai.CalculatorService:Result of the add method:5
com.replace.dai.CalculatorService:The add method ends.
com.replace.dai.CalculatorService:Result of the add method:5
com.replace.dai.CalculatorService:The add method ends.
5
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值