Announcement Announcement Module
Collapse
No announcement yet.
combining pointcut expressions? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • combining pointcut expressions?

    Hello there!

    I have the DAO interface, which provides the method of getting an entity by ID. Earlier there was the requirement: the user can not load the entity he's not owning (but apparently he knows the ID somehow).

    I have implemented the before advice on the load entity method of the DAO implementation, which throws an exception. This works fine.

    But now I need to have additional advice to be applied to the same method, which changes the returned object (so it looks like after advice needs to be implemented).

    The question is - how can I have 2 advices on the same method of the same DAO instance, which aren't interfere? I know the method of the DAO will be called from 2 different controllers (lets say A and B).

    In the controller A the advice, which checks the ownership of the entity and throws an exception if user does not own the object, needs to be applied to the DAO method.

    In the controller B the advice, which allows to get the object from the persistent storage, and them modifies the loaded object, needs to be applied and NO exception needs to be thrown.

    I've read about "within" pointcut expression, and redefined my pointcut in this way:
    Code:
            <aop:aspect
                ref="restrictOwnerAdvice">
                <aop:pointcut
                    id="restrictOwner4SimpleFaceDao"
                    expression="execution(* dao.face.ibatis.IBATISSimpleFaceDao.loadSimpleFace(core.entity.face.UniqueEntityInterface))
                    and within(web.ui.controller.SimpleFaceManagementController.*)
                    and args(uuidHolder)" />
                <aop:before
                    method="doAccessCheck"
                    pointcut-ref="restrictOwner4SimpleFaceDao" />
            </aop:aspect>
        </aop:config>
    However for some reason the advice is not called, looks like pointcut is not matched? Am I understanding the within expression correctly - it should match the method, which calls the adviced method?

    Thank you!

  • #2
    1. You said that the 'before' aspect worked fine. So, pointcut matched necessary method invocation, hence, you shouldn't change it;
    2. You asked 'how can I have 2 advices on the same method of the same DAO instance, which aren't interfere'. You need to have two aspects here, not two advice. So, you define two separate aspects and set correct processing order - check reference for details (6.2.4.7. Advice ordering);
    3. It's not possible to say exactly if mentioned pointcut is correct. It looks correct on its own but it's not possible to say if particular aspect that uses the pointcut works fine with particular system;

    Comment


    • #3
      Yes, the before advice works fine, except one small thing:

      it is invoked when the DAO method is called from any of controllers A and B, which is wrong - I need to have only the Before advice to be invoked when the DAO method is called from the controller A, and After advice only has to be called when the DAO method is called from the controller B.

      I tried to gain this goal with adding "within" clause to the pointcut expression - but no luck. I specified the Before advice needs to be invoked when the adviced method from DAO is called from the controller A - and this doesn't work. The advice is never called - so pointcut is never matched. An unfortunately I don't have any idea of how to debug the Spring AOP pointcut matchers

      I've noticed the method in the controller A, which used to invoke the service method of the DAO, looks like this:

      Code:
         /**
           * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
           */
          @Override
          protected Object formBackingObject(final HttpServletRequest request)
                  throws Exception {
              final String faceId = ServletRequestUtils.getStringParameter(request,
                      "face");
              // TODO check if the customer wants to load it's own
              if (faceId != null) {
                  return simpleFaceDao
                          .loadSimpleFace(new UniqueEntityInterface<UUID>() {
      
                              @Override
                              public UUID getUuid() {
                                  return UUID.fromString(faceId);
                              }
                          });
              }
              return new SimpleFace();
          }
      May it happen the "protected" modifier of the method formBackingObject violates the matching of the "within" expression?
      Last edited by jdevelop; Nov 5th, 2008, 04:21 PM.

      Comment


      • #4
        Please correct me if I'm wrong:

        the WITHIN pointcut expression defines just a type, which declares the methods, being matched by the pointcut expression.

        This means it is not possible to write down the controller class, define the method formBackingObject in this controller class, inside this method call the method of the DAO instance - and create the pointcut expression, which will match the EXECUTION of the DAO method WITHIN the controller method.

        It seems the within keyword does not relies on the calling stack to perform the match - it just grasps the static scope of the method definition.

        So in general the task I want to solve - write the pointcut expression, which checks the place from where the EXECUTION was invoked from - can't be solved with Spring AOP (may be AspectJ?)

        Comment


        • #5
          You can exploit AspectJ 'call' pointcut designator in conjunction with 'within'. I posted example of the 'call' usage at the forum earlier - Any way for the advice to know the calling object?

          Comment

          Working...
          X