`
laolinshi
  • 浏览: 40957 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论
阅读更多

     前段时间研究了Spring的AOP功能,觉得这个功能挺不错的,希望有机会可以用到自己的项目中。正好这个时候正在做的一个项目需要日志管理的功能,我不想和以前的做法一样,把日志功能的代码直接和业务逻辑的代码交织在一起,这样做不但不利于后期的维护,还可能影响系统的逻辑功能。舍弃了这种做法,AOP就可以派上用场了。

    

     但实际使用的时候发现,AOP也不是书上讲的那么容易,期间遇到了很多问题需要解决。现在我把遇到的问题列举如下:

(1)项目中是使用了事物的,是通过spring实现的。刚开始没有考虑到系统要用AOP的时候,实现事务的功能是直接在spring容器中配置一个含有事务功能的抽象类,然后所有需要事务功能的类就继承这个类。现在涉及到AOP了,就需要拦截这些继承了事务功能的类的某些方法以便做日志记录。但这样做了,spring容器就起不来了,总是抱错说添加了日志拦截功能的类无法初始化。试了很多次都不行,无奈只好到网上去找解决问题的办法了。功夫不负有心人,找了一个下午,终于找到了一些有用的资料。有一篇文章上给出的问题和我现在遇到的问题是很相似的,但没有给出引起这种错误的具体原因,只是给出了解决问题的方法,按找这种方法试了,spring容器真的不再出现这种问题,顺利启动了,而且可以实现相应的功能。方法很简单,就是实现事务的方式由继承改成AOP代理就可以了,使用的是注解的方式。这样做管理事务就更加方便了,直接去掉代理就可以了,不用在每个bean里面去掉abstract属性这样麻烦。关键代码如下:

   <!-- 事务通知 -->  
   <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
   <tx:method name="insert*" propagation="REQUIRED" />
   <tx:method name="add*" propagation="REQUIRED" />
   <tx:method name="del*" propagation="REQUIRED"/>
   <tx:method name="modify*" propagation="REQUIRED"/>
   <tx:method name="up*" propagation="REQUIRED"/>
   <tx:method name="import*" propagation="REQUIRED"/>
  </tx:attributes>
 </tx:advice>
      
    <!-- aop代理设置   -->
    <aop:config proxy-target-class="true">  
        <aop:pointcut id="txPointcut" expression="execution(* cn.ipanel.apps.cms..service.impl.*.*(..))"/>  
  <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
 </aop:config>

在这种情况下,日志记录的方式,我也用注解的方式实现了。通过这种方式,日志逻辑和业务逻辑就较好的分开了,方便日志代码的维护管理。

 

(2)但AOP注解的方式并不是任何方法都可以拦截,我在拦截Action中的方法是就遇到了这个问题,不管怎样试,拦截的方法都不起作用,且没有任何报错的信息。这让我非常苦恼,差点就要放弃了。无可奈何之下,带着这个问题请教了一个老同事,他看了几下配置文件后指出,struts中的Action没有实现接口,导致AOP无法发挥作用的关键。现在解决的办法有两个:一是为每个Action实现一个接口,然后就可以用这种方式了,但这样做觉得很别扭,且失去了接口的意义了,纯粹为了AOP 的情况下。基于以上考虑,放弃了这种方式。二是不用注解,采用Proxy的方式,可以顺利解决问题,但必须为每个Action类配置一个代理bean,很繁琐。在没有想到更好的方式之下,我就采用了第二中方法。通常记录日志都需要用户信息,在Action中就很容易得到这类信息,所以我才采取在Action层进行拦截的方式,虽然知道这种方式不好,但没办法。不然的话,只能为每个service方法传递一个user的对象了,但当初没有考虑到这个,现在实现起来也要做很多的修改,所以放弃了。配置文件中关键代码摘抄如下:

<bean name="/module/importXml"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target">
            <ref local="importAndExportXml" />
        </property>
        <property name="interceptorNames">
            <value>importAndExportNodeXmlLoginfoAdvice</value>
        </property>
        <property name="proxyTargetClass" value="true"/>
    </bean>

   

   上面就是我在项目中应用AOP时遇到的主要问题,都解决了,希望可以对其他的人有帮助。

 

 

分享到:
评论
1 楼 xuedong 2011-08-09  
不错,关注下,呵呵

相关推荐

Global site tag (gtag.js) - Google Analytics