Announcement Announcement Module
Collapse
No announcement yet.
Can I use an AOP in a method called by a method of same Object ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can I use an AOP in a method called by a method of same Object ?

    Hi, I've got an object A which implements an interface (RohanSequencer).
    This interface has 2 public methods : execute and doInTransaction.

    I want to put an aspect for transaction management around "doInTransaction".

    "doInTransaction" is called by "execute" method and it seems not to work. if I call "doInTransaction" outside the "execute" Method (i.e, immediately after called applicationContext.getBeans on object A ), it works.

    Here's a fragment of my Spring configuration :

    <bean id="transactionManager"
    class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <aop:config>
    <aopointcut id="sequencerIntercept"
    expression="execution(* com.rohan.sequencer.api.RohanSequencer.doInTransac tion (..))" />
    <aop:advisor advice-ref="transactionSequencerAdvice" pointcut-ref="sequencerIntercept" />
    </aop:config>

    <tx:advice id="transactionSequencerAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method name="doInTransaction" propagation="REQUIRED" />
    </tx:attributes>
    </tx:advice>

    Is there a way to solve the problem ? Without split my 2 methods in two differents object ?

    Regards,
    E. Lewandowski

  • #2
    I suggest you read chapter 6.6.1 of the reference guide. That explains how Spring AOP works.

    Spring AOP uses a proxy based approach, so only call INTO the object are intercepted/adviced. As soon as you are inside your object you don't pass through the proxy anymore and nothing is intercepted.

    If you want that to happen use loadtime or compiletime weaving, you have to use a full blown solution like AspectJ for that.

    You could also use programmatic transaction management to fix it, however that would couple your code to Spring. You could use the TransactionTemplate for that.

    Or (the very ugly solution imho) make your object aware of a proxy and call the method in the proxy. (Or make the object aware of itself and call it from there, also ugly imho).

    The easiest workaround is to make it aware of the ApplicationContext and its own name and let the bean pull itself from the context and call the doInTransaction method on that. By implementing the BeanNameAware and ApplicationContextAware interface, then instead of calling this.doInTransaction, use context.getBean(beanName).doInTransaction(). Still ugly but it will work.

    Comment


    • #3
      Originally posted by Marten Deinum View Post
      If you want that to happen use loadtime or compiletime weaving, you have to use a full blown solution like AspectJ for that.
      It is pretty simple actually, and you have everything you need in the Spring distro.
      Check out http://static.springframework.org/sp...tml#aop-aj-ltw

      Comment


      • #4
        Thanks for all your suggestions !

        Comment

        Working...
        X