动态代理
代理可以为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能。例如,异常处理,日志,计算方法的运行时间,事务管理等。
JDK中为我们提供了动态代理。
Class clazzProxy = Proxy.getProxyClass(Collection.class
.getClassLoader(), Collection.class);// 获取动态代理的字节码实例
Constructor constructor = clazzProxy
.getConstructor(InvocationHandler.class);// 利用反射取得构造器
Collection proxyInstance = (Collection) constructor
.newInstance(new InvocationHandler() {// 进行实例化,需实现InvocationHandler接口
public ArrayList target = new ArrayList();// 目标对象
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object retValue = method.invoke(target, args);
return retValue;
}
});
proxyInstance.add("java01");
proxyInstance.add("java02");
System.out.println(proxyInstance.size());
System.out.println(proxyInstance.getClass());
上例中实例化代理对象时要实现InvocationHandler接口。代理对象调用方法时,都会转到InvocationHandler的invoke方法,最后对目标对象进行方法调用。
注意:代理类继承自Object的方法除了toString(),hashCode(),equals()经过invoke方法外,其他方法都是由代理类自己实现。
我们可以在invoke方法中增加代码以实现额外功能。
public static Object getProxyInstance(final Object target,final MyAdvice advice) {
return
Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[] {Collection.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
advice.beforeMethod();
Object retValue = method.invoke(target,args);
advice.afterMethod();
return retValue;
}
});
}
自定义类MyAdvice
public class MyAdvice {
public long beginTime;
public long endTime;
public void beforeMethod(){
beginTime = System.currentTimeMillis();
System.out.println("方法前");
}
public void afterMethod(){
System.out.println("方法后");
endTime = System.currentTimeMillis();
System.out.println("方法运行时间为" +(endTime-beginTime) );
}
}
测试如上方法
ArrayList array = new ArrayList();
MyAdvice advice = new MyAdvice();
Collection proxy3 = (Collection) getProxyInstance(array,advice);
proxy3.add("java02");
System.out.println(proxy3.size());
如此只要调用proxy3的任何方法都可以计算出调用方法的时间。
注意:动态代理只能针对拥有接口的类,如果没接口就没法实现。这时候如果要使用代理可以使用第三方cglib.
代理是AOP编程的核心技术,学好代理能更好地理解AOP编程。