特点:许多解决解决问题的方法中的共同点提取出来。实现时利用java api的代理类实现,需要对工具类进行学习。
实际情况:需要对某个对象或一组对象,进行功能扩展,动态增加和取消特定功能。如日志记录功能。
优点是:把我们的代理对象和被代理对象解藕,代理者和操作者解藕。
缺点:
实现:
package sinosoft.dj.aop.proxyaop;
import java.lang.reflect.Method;
public interface IOperation {
void start(Method method);
void end(Method method);
}
实现上面接口的类.生成一个真正的操作者,如下面是日志操作者的一个类:
LoggerOperation.java
package sinosoft.dj.aop.proxyaop;
import java.lang.reflect.Method;
public class LoggerOperation implements IOperation {
public void end(Method method) {
Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
}
public void start(Method method) {
Logger.logging(Level.INFO, method.getName() + " Method Start!");
}
}
然后我们要改一下代理对象DynaProxyHello中的代码.如下:
package sinosoft.dj.aop.proxyaop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynaProxyHello implements InvocationHandler {
private Object proxy;
private Object delegate;
//这个band的方法参数有几个有没有约定?
public Object bind(Object delegate,Object proxy) {
this.proxy = proxy;
this.delegate = delegate;
return Proxy.newProxyInstance(
this.delegate.getClass().getClassLoader(), this.delegate
.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
try {
//反射得到操作者的实例
Class clazz = this.proxy.getClass();
//反射得到操作者的Start方法
Method start = clazz.getDeclaredMethod("start",
new Class[] { Method.class });
//反射执行start方法
start.invoke(this.proxy, new Object[] { method });
//执行要处理对象的原本方法
result = method.invoke(this.delegate, args);
// 反射得到操作者的end方法
Method end = clazz.getDeclaredMethod("end",
new Class[] { Method.class });
// 反射执行end方法
end.invoke(this.proxy, new Object[] { method });
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
测试一下:
package sinosoft.dj.aop.proxyaop;
public class Test {
public static void main(String[] args) {
IHello hello = (IHello)new DynaProxyHello().bind(new Hello(),new LoggerOperation());
hello.sayGoogBye("Double J");
hello.sayHello("Double J");
}
}
实践:写一个记录日志的工具类通过动态代理类。