0

I'm really having problem in advicing methods with pointcuts expressions. I have the following configuration:

Spring 3.1.2.RELEASE

pom.xml

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.2</version>
    </dependency>

servlet.xml

    <aop:aspectj-autoproxy/>

the class I want to advice

@Repository(value="userDaoImpl")
@Transactional
public class UserDaoImpl implements UserDao{

    //attributes and methods

    @Override
    public void delete(ProfiledUser user) throws HibernateException
    {
        sessionFactory.getCurrentSession().delete(user);        
    }
}

it implements the UserDao Interface which extends a GenericDao<T> Interface

here's my Advice

@Aspect
@Component("userDeletionAspect")
public class UserDeletionAspect {

    @Pointcut("execution(public void aa.bb.cc.dd.UserDaoImpl.delete(..))")
    public void objectDeletionPointcut(){}

    @Before("objectDeletionPointcut()")
    public void notifyDeletion(JoinPoint jp)
    {       
        System.out.println("pointcut executed");
    }
}

which doesn't work. It means that when the UserDaoImpl's delete method is executed it isn't intercepted at all.

From Spring Documentation I read that spring proxies work with Interfaces so I tried to change the Pointcut definition as follow:

  @Pointcut("execution(* aa.bb.cc.dd.GenericDao.delete(..))")

but nothing changes. How can I intercept the .delete() method of the UserDaoImpl class?

MaVVamaldo
  • 2,505
  • 7
  • 28
  • 50

1 Answers1

1

You need

<aop:aspectj-autoproxy>
    <aop:include name="userDeletionAspect"/>
</aop:aspectj-autoproxy>

instead of

<aop:aspectj-autoproxy/>

FYI - You can target either concrete classes or implementations of a specific interface in your pointcut expressions.

Spring can only target public methods so you can remove the 'public' part from your pointcut expressions. Also, if you want you can declare your advice along with the pointcut expression like so:

@Before("execution(void aa.bb.cc.dd.UserDaoImpl.delete(..))")
public void notifyDeletion(JoinPoint jp) {       
     System.out.println("pointcut executed");
}

You should be good to go now, but If you are still having some issues, here's a simple logging example using Spring AOP - logging with AOP in spring?

Community
  • 1
  • 1
Markus Coetzee
  • 3,384
  • 1
  • 29
  • 26
  • unluckily, even changing the code as you suggest I still can't intercept that delete() method. I use the @Trasactional annotation at Dao class level, so all the Dao methods (including my delete() method) are already proxied by TransactionInterceptor class. Can it affect my interception attempt? – MaVVamaldo May 11 '13 at 19:22
  • 1
    Adding the transactional annotation wont cause any issue. In my Spring MVC app I successfully target some advice at my controller which is annotated with @Transactional. Firstly, is your 'servlet.xml' your application context? Secondly, have you configured Spring to scan your UserDeletionAspect class's package so that it can add it as a bean to the container? – Markus Coetzee May 11 '13 at 20:33
  • bingo! My Dao classes were annotated with @Repository stereotype and... they did their work, so I thought they were registered to the container somehow. It seems it isn't enough for AOP. I added `` and everything works like a charm. I'm just a little concerned that these classes will be registered twice. – MaVVamaldo May 11 '13 at 21:06
  • I'm glad you got it working :) Annotated classes wont get added to the container unless you tell Spring to scan for them in their respective packages, so you don't have to worry about it being registered twice. But lets say you declared the repository as a bean in XML as well as annotated it, and you told Spring to scan it's package, then you would probably run into problems when your application context boots up. – Markus Coetzee May 11 '13 at 21:22