动态代理的作用(个人理解):
可以实现类似拦截器的功能,比如执行某个方法前后,需要执行一些其它操作(如开启关闭事务,记录日志、权限校验等)。
不足(个人理解):
目前仅能创建指定接口的动态代理,如果需要为某个类(该类未实现任何接口)创建动态代理,则无能为力了(实际上通过另外一个开源框架cglib也是可以实现的,只是java本身未提供该功能)。
示例:
接口IHelloWorld
public interface IHelloWorld { public String sayHello(String name); }
实现类HelloWorld:
public class HelloWorld implements IHelloWorld{ public String sayHello(String name){ System.out.println("执行sayHello()"); return "hello,"+name; } }
自定义handler:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { //源对象,即被代理对象 private Object sourceObj; /* * 构造函数 */ public MyInvocationHandler(Object sourceObj){ this.sourceObj = sourceObj; } /* * 对源对象的所有方法进行拦截,在源方法执行前、执行后,分别加入一些处理。 */ public Object invoke(Object proxyObj, Method method, Object[] arg)throws Throwable { System.out.println("执行"+method.toString()+"之前"); Object returnValue = method.invoke(sourceObj, arg); System.out.println("执行"+method.toString()+"之后"); return returnValue; } }
代理工厂:
import java.lang.reflect.Proxy; public class ProxyFactory { /* * 获得代理对象 */ public static Object getProxyObj(String clazz) throws Exception{ Object sourceObj = Class.forName(clazz).newInstance(); return Proxy.newProxyInstance(sourceObj.getClass().getClassLoader(), sourceObj.getClass().getInterfaces(), new MyInvocationHandler(sourceObj)); } }
测试类:
public class Test { public static void main(String[] args) { try { //须用接口来接收 IHelloWorld hello = (IHelloWorld)ProxyFactory.getProxyObj(HelloWorld.class.getName()); System.out.println("返回结果:"+hello.sayHello("huangqiqing")); } catch (Exception e) { e.printStackTrace(); } } }
输出结果:
执行public abstract java.lang.String IHelloWorld.sayHello(java.lang.String)之前
执行sayHello()
执行public abstract java.lang.String IHelloWorld.sayHello(java.lang.String)之后
返回结果:hello,huangqiqing