从JDK1.3以后,Java提供了动态代理的机制。动态代理是一种强大的语言结构,可以为一个或多个接口创建代理对像而不需要预先用于一个接口的实现类。Java中的动态代理机制可以方便地用于实现AOP。
考虑如下情形:当需要为多个不具有继承层次的对象引入同一个公共行为的时候,例如记录日志,安全检查等等。如果考虑用OOP的思想进行设计,需要为每一个对象实现相同功能的记录日志或者安全检查的方法,这样,虽然能解决问题,但是其代价就是在程序中存在大量的重复性代码。如下图:
那么,如何才能更好的解决此问题呢?此时需要用到AOP(面向切面编程)的思想。而利用java中的动态代理机制就能很容易的实现AOP。实现机制如下图所示:
用java动态代理机制实现的具体步骤如下(以日志记录为例):
1.
package com.test.proxy;
public interface Log {
public void logging();
}
2.
package com.test.proxy;
public class LogImpl implements Log {
public void logging(){
System.out.println("=====logging方法执行,写入日志======");
}
}
3.
创建并编写代理类
LogProxy.java
。此类实现了
java
提供的
InvocationHandler
接口。通过这个代理类,可以在运行是自动创建指定接口的代理对象,并由此代理对象完成相关业务逻辑流程。
package com.test.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
private Object proxyObj;
public LogProxy(Object obj) {
this.proxyObj = obj;
}
@SuppressWarnings("unchecked")
public static Object bind(Object obj) {
Class cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), new LogProxy(obj));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
dobefore(method);
Object object = method.invoke(proxyObj, args);
doafter(method);
return object;
}
private void dobefore(Method method) {
prt("方法" + method.getName() + "執行前");
}
private void doafter(Method method) {
prt("方法" + method.getName() + "執行后");
}
public void prt(String msg) {
System.out.println(msg);
}
}
4.
创建并编写测试类
TestLog.java
package com.test.proxy.test;
import com.test.proxy.LogProxy;
import com.test.proxy.LogImpl;
import com.test.proxy.Log;
public class Testlog {
public static void main(String[] args) {
// TODO Auto-generated method stub
Log login = (Log)LogProxy.bind(new LogImpl());
login.logging();
}
}
执行后的结构如下:
通过上述步骤,即完成了简单的java的动态代理。