读书人

运用java动态代理机制实现AOP是丑陋的

发布时间: 2012-10-30 16:13:36 作者: rapoo

使用java动态代理机制实现AOP是丑陋的
我们知道,AOP实现,一般要尽可能的透明化。业务类是不管这些切面的。实现的方法,一般都是拦截器,或者类似AspectJ那样的代码生成工具。如果使用动态代理,直接写的话,会使代码很丑陋。我宁可采用别的方法实现。除非实现某个规则约束。但是这样的话就不透明了。所以,生成代码的模式更好一些。
但是我们在程序里面生成代码,似乎是一件比较奇怪的事情。就好像我们在干jvm干的活。感觉有些怯怯的。想和大家讨论一下。听听大家的意见。另外AOP还有什么实现原理呢?

另外,使用动态代理似乎效率不是很高。
   o = method.invoke(delegate,args);
   logger.info("method ends..." + method);
  } catch (Exception e){
   logger.info("Exception happends...");
   //excetpion handling.
  }
  return o;
 }
} </pre>
<p>下面是客户端调用代码:</p>
<pre name='code' class='java'>BusinessInterface businessImp = new BusinessObject();

InvocationHandler handler = new LogHandler(businessImp);

BusinessInterface proxy = (BusinessInterface) Proxy.newProxyInstance(
 businessImp.getClass().getClassLoader(),
 businessImp.getClass().getInterfaces(),
 handler);

proxy.processBusiness(); </pre>
<p>?businessImp是我们的一个业务实现。我为什么说这种方法比较丑陋呢?就是使用了这些和业务无关的接口和Proxy代理类。虽然这些是jdk提供的,但是给我的感觉是我在写一些和我应用无关的代码。当然上面仅仅是一个简单的示例。也可以想一些办法封装这些操作。但是总给我的感觉是有些怪异,所以希望问一下还有其他的什么实现。惭愧。写这些内容的时候,深感自己水平不行,贻笑大方了。不过刚才想想我的这个帖子标题,的确不好,不应该用这种结论式的标题。给人感觉不好。其实我是想和人探讨的。</p>   o = method.invoke(delegate,args);
   logger.info("method ends..." + method);
  } catch (Exception e){
   logger.info("Exception happends...");
   //excetpion handling.
  }
  return o;
 }
} </pre>
<p>下面是客户端调用代码:</p>
<pre name='code' class='java'>BusinessInterface businessImp = new BusinessObject();

InvocationHandler handler = new LogHandler(businessImp);

BusinessInterface proxy = (BusinessInterface) Proxy.newProxyInstance(
 businessImp.getClass().getClassLoader(),
 businessImp.getClass().getInterfaces(),
 handler);

proxy.processBusiness(); </pre>
<p>?businessImp是我们的一个业务实现。我为什么说这种方法比较丑陋呢?就是使用了这些和业务无关的接口和Proxy代理类。虽然这些是jdk提供的,但是给我的感觉是我在写一些和我应用无关的代码。当然上面仅仅是一个简单的示例。也可以想一些办法封装这些操作。但是总给我的感觉是有些怪异,所以希望问一下还有其他的什么实现。惭愧。写这些内容的时候,深感自己水平不行,贻笑大方了。不过刚才想想我的这个帖子标题,的确不好,不应该用这种结论式的标题。给人感觉不好。其实我是想和人探讨的。</p></div><br/>直接用动态代理代码是这样写的,但是用spring或者其他什么框架,你只需要写invoke里面的代码,其他那些机械式都是封装好的 7 楼 movingboy 2008-05-06 单单从代码来看,似乎也就是这样做吧?似乎Guice提供了Annotation来替代手工创建proxy的代码,而Spring则是用配置来实现(不清楚Spring是否也提供了annotation) 8 楼 dennis_zane 2008-05-06 动态代理可以玩的很花巧,这可能就是楼主所说的“丑陋”,用AspectJ未尝不可,就是多了个学习成本的问题,而spring等框架已经封装的很好了 9 楼 christensen 2008-05-06 感觉如果这么实现的话,用不用aop都差不多。

aop不适合做日志

10 楼 christensen 2008-05-06 你这么实现不是aop的概念,其实就是代理模式么 11 楼 anlibo 2008-05-06 这个怎么感觉不像动态代理来着 12 楼 movingboy 2008-05-06 我认为动态代理要与容器配合使用才能发挥威力,应用程序只关心业务逻辑,而生成代理的过程由容器来自动完成;自己手工写代理代码确实把业务逻辑和代理逻辑混在一起了,维护、扩展都比较麻烦
如果自己把代理逻辑抽象出来,与业务逻辑分离,你会发觉就象是在做一个容器。既然如此,为什么不用现成的、成熟的容器呢? 13 楼 zhxp791008 2008-05-07 你可以将业务代码调用动态代理的代码进行封装。这样在业务代码中就没有你所说的那么多丑陋的代码了。。 14 楼 clarkhill 2008-05-07 其实我的意思是,实现aop的方式,动态代码生成,比如使用aspectj或者asm要比使用动态代理要好一些。想问问大家的想法。 15 楼 alexma 2008-05-07 我也觉得楼主是否可以尝试用容器呢,比如 Spring ,可以让你的业务代码变得很干净。 16 楼 bulargy 2008-05-07 movingboy 写道单单从代码来看,似乎也就是这样做吧?似乎Guice提供了Annotation来替代手工创建proxy的代码,而Spring则是用配置来实现(不清楚Spring是否也提供了annotation)
spring2.5是可以用aonntation来做aop的~~~ 17 楼 flyromza 2008-05-07 clarkhill 写道其实我的意思是,实现aop的方式,动态代码生成,比如使用aspectj或者asm要比使用动态代理要好一些。想问问大家的想法。

bci当然比dynamic proxy要来的更加的好,运行时怎么也比不过编译时或装载时,不过么有免费的午餐,技术难度也不可同日而语。 18 楼 szhnet 2008-05-07 可以用spring的封装 19 楼 aninfeel 2008-05-07 本来就无所谓丑陋,优雅的调用总是要封装一些丑陋的代码。 20 楼 senbao18 2008-05-07 spring可以封装,可以参照一下源码~~~

读书人网 >软件架构设计

热点推荐