创建接口
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