Java中的静态代理和动态代理
1. 代理模式主要有两种:静态代理和动态代理
2. 静态代理:
比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
package ttitfly.proxy; public interface HelloWorld { public void print(); // public void say(); } package ttitfly.proxy; public interface HelloWorld { public void print(); // public void say(); }
package ttitfly.proxy; public class HelloWorldImpl implements HelloWorld{ public void print(){ System.out.println("HelloWorld"); } // public void say(){ // System.out.println("Say Hello!"); // } } package ttitfly.proxy; public class HelloWorldImpl implements HelloWorld{ public void print(){ System.out.println("HelloWorld"); } // public void say(){ // System.out.println("Say Hello!"); // } }
package ttitfly.proxy; public class StaticProxy implements HelloWorld{ public HelloWorld helloWorld ; public StaticProxy(HelloWorld helloWorld){ this.helloWorld = helloWorld; } public void print(){ System.out.println("Welcome"); //相当于回调 helloWorld.print(); } // public void say(){ // //相当于回调 // helloWorld.say(); // } } package ttitfly.proxy; public class StaticProxy implements HelloWorld{ public HelloWorld helloWorld ; public StaticProxy(HelloWorld helloWorld){ this.helloWorld = helloWorld; } public void print(){ System.out.println("Welcome"); //相当于回调 helloWorld.print(); } // public void say(){ // //相当于回调 // helloWorld.say(); // } }
package ttitfly.proxy; public class TestStaticProxy { public static void main(String[] args){ HelloWorld helloWorld = new HelloWorldImpl(); StaticProxy staticProxy = new StaticProxy(helloWorld); staticProxy.print(); // staticProxy.say(); } } package ttitfly.proxy; public class TestStaticProxy { public static void main(String[] args){ HelloWorld helloWorld = new HelloWorldImpl(); StaticProxy staticProxy = new StaticProxy(helloWorld); staticProxy.print(); // staticProxy.say(); } }
package ttitfly.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类 public class DynamicProxy implements InvocationHandler{ private Object object; //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。 //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法 public Object bindRelation(Object object){ this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this); } //拦截关联的这个实现类的方法被调用时将被执行 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Welcome"); Object result = method.invoke(object, args); return result; } } package ttitfly.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //动态代理类只能代理接口,代理类都需要实现InvocationHandler接口,覆盖invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类 public class DynamicProxy implements InvocationHandler{ private Object object; //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。 //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法 public Object bindRelation(Object object){ this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this); } //拦截关联的这个实现类的方法被调用时将被执行 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Welcome"); Object result = method.invoke(object, args); return result; } }
package ttitfly.proxy; public class TestDynamicProxy { public static void main(String[] args){ HelloWorld helloWorld = new HelloWorldImpl(); DynamicProxy dp = new DynamicProxy(); //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。 HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld); helloWorld1.print(); helloWorld1.say(); //helloWorld2将不被拦截 HelloWorld helloWorld2 = new HelloWorldImpl(); helloWorld2.print(); helloWorld2.say(); } } package ttitfly.proxy; public class TestDynamicProxy { public static void main(String[] args){ HelloWorld helloWorld = new HelloWorldImpl(); DynamicProxy dp = new DynamicProxy(); //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。 HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld); helloWorld1.print(); helloWorld1.say(); //helloWorld2将不被拦截 HelloWorld helloWorld2 = new HelloWorldImpl(); helloWorld2.print(); helloWorld2.say(); } }