Java动态代理实现
JDK1.2以后提供了动态代理的支持,程式员通过实现java.lang.reflect.InvocationHandler接口提供一个执行处理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行商业方法,在商业方法被调用的同时,执行处理器会被自动调用。
下面我讲用JAVA代码为大家展示Java动态代理的作用
首先假设我们有个一逻辑业务成,分为很多处理逻辑业务的方法,在调用逻辑业务时候,我们必须为其建立日志,我们一般的做法如下:
Public interface doLogicDao()
{
Public void doAdd();
Public void doDelete();
Public void doModify();
}
Public class doLogicDaoImp1 implements()
{
//---voerride each method
Public void doAdd()
{
System.out.println("进行增加操作");
}
Public void doDelete()
{
System.out.println("进行删除操作");
}
Public void doModify()
{
System.out.println("做更改操作");
}
}
噢噢噢,搞忘了,doLogicDaoImp类不应该这样写,我们还要记录日志呢!!!哈哈,笨,让我们来更改一下
Public class doLogicDaoImp implements()
{
//---voerride each method
Public void doAdd()
{
doLog();
System.out.println("进行增加操作...");
}
Public void doDelete()
{
doLog();
System.out.println("进行删除操作...");
}
Public void doModify()
{
doLog();
System.out.println("做更改操作...");
}
Public void doLog()
{
System.out.println("我正在记录日志呢...");
}
}
具体实现大家应该都明白了吧,我也不说那么多了,毕竟我也是个新手
当然,这样还是很简单,应为逻辑方法太少了,操作起来是非常简单的.假如有几十个doLogicDaoImp1,doLogicDaoImp2,等逻辑实现类呢?你还是用Ctrl+v吗?显然不是,那我们有什么更好的方法呢?
答案很肯定,我们应该用JAVA的动态代理机制
在引入JAVA动态代理机制之前,我们必须先了解一个接口InvocationHandler还有Proxy类,InvocationHandler接口定义了一个invoke方法,参数有(Object arg0, Method arg1, Object[] arg2) arg0 表示被代理的对像,arg1表示被代理对象的方法,arg2表示方法arg1的参数列表 ,并且invoke方法不会显式的去调用,而是被JVM
调用, Proxy类中定义了静态方法newProxyInstance()该方法返回代理类的实列,
好,说了这么一点点,那让我们来看看,上面的列子该怎么去改了,
首先先写个代理类,代理所有的逻辑处理过程
public class LogicHandler implements InvocationHandler {
private Object targetObj;
public Object newProxy(Object targetObj) {
this.targetObj = targetObj;
System.out.println(targetObj.getClass().getName());
System.out.println("this--->" + this.getClass().getName());
Return
Proxy.newProxyInstance(targetObj.getClass().getClassLoader(),
targetObj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
// TODO Auto-generated method stub
doLog();
System.out.println("invoke:-->"+arg0.getClass().getName());
System.out.println("methord name=" + arg1.getName());
for (int i = 0; i < arg2.length; i++) {
System.out.println(arg2[i]);
}
Object result = null;
try {
result = arg1.invoke(targetObj, arg2);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("r-------->"+result);
return result;
}
public void doLog() {
System.out.println("我正在记录日志呢...");
}
}
该类中的System.out.println();只供测试用,兄弟们也可以一个个的测试下其他参数的输出结果,以便更家了解这东东
这样,我们就很好的解决了这个问题,在主函数中调用:
LogicHandler logic = new LogicHandler();
DoLogicDao doit = (DoLogicDao)logic.newProxy(new DoLogicDaoImp());
Doit.delete();
Doti.add();
好,大功告成,谢谢大家的支持