0

I have a controller class like below:

@Controller
class X extends BaseController{ 
    @RequestMapping()
    public String getX(){
    }
}

public class BaseController implements ServletContextAware {
}

I am trying to add an aspect as shown below:

@Service
@Aspect
public class Foo{
   @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
   public Object profileControllerAction(ProceedingJoinPoint pjp) 
                 throws Throwable {
      // do stuff
   }
}

But, the aspect method is not called. I expect it to be executed when getX() of the controller is called.

I see that spring mvc did not wrap my controller bean with a proxy. Is that the reason why the aspect was not effective?

Can anyone explain how I can get the aspect called.

The controller classes are in : com.xyz.webapp.controller

The Aspect class is in com.xyz.webapp

The context file is in WEB-INF.
The context xml is:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"          
    default-lazy-init="true">
    <context:annotation-config/>  
    <context:component-scan base-package="com.xyz"/>    
    <aop:aspectj-autoproxy />

    <aop:config>  
        <aop:advisor id="serivcesApiAdvice" advice-ref="serivcesAdvice" pointcut="execution(* *..provider.*.*(..))" order="1"/>        
    </aop:config>   
    <bean id="serivcesAdvice" class="com.xyz.webapp.spring.xyzMethodInterceptor"/>    
</beans>

----- more details --- I added the following code in one of our controller methods.The list has all of controllers and the aspect I wrote too. Actually, I think it is listing all of our beans. How can I see what all application contexts are living in the application at runtime ?

ApplicationContext context = ApplicationContextProvider.getApplicationContext();
System.out.println("context name:" + c.getDisplayName());
for(String s : context.getBeanDefinitionNames()){
    System.out.println(s);
}

The context name it printed is:Root WebApplicationContext

user19937
  • 587
  • 1
  • 7
  • 25

1 Answers1

1

The aspect configuration in a context applies only to that context. It can only process those beans declared there.

Spring uses a parent-child relationship between its root context and servlet context. As such, the rule expressed above doesn't apply. If you want your controllers to be proxied for the additional aspect behavior, you will need to add the aspect configuration to your servlet context which scans and generates the @Controller beans.

Note that it seems like you are doing redundant configuration. Your (I'll assume) root context is scanning packages (containing the @Controller classes) that should be scanned by the servlet context. Don't do that or you might end up with two beans or injection errors.

Also,

<context:annotation-config/>  

is redundant if you specify

<context:component-scan base-package="com.xyz"/>    

You can get rid of it.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • in the web.xml, the following configuration is found. contextConfigLocation classpath:/applicationContext-x.xml classpath:/applicationContext-y.xml classpath:/applicationContext-z.xml classpath*:/applicationContext.xml is this what you mean by "controller classes should be scanned by servlet context" – user19937 Mar 05 '14 at 22:11
  • @user19937 No. [Read this.](http://stackoverflow.com/questions/11708967/what-is-the-difference-between-applicationcontext-and-webapplicationcontext-in-s) What you're showing me is the configuration for the `ContextLoaderListener`. That's the root context. You should also have a servlet context loaded by the `DispatcherServlet`. – Sotirios Delimanolis Mar 05 '14 at 22:13
  • thank you for the pointers. I updated my post with some details. – user19937 Mar 07 '14 at 00:37
  • I checked what "ApplicationContext" objects are in the system by attaching yourkit. It shows me two entries. Is this normal ? id "org.springframework.web.context.WebApplicationContext:/dispatcher" displayName "WebApplicationContext for namespace 'dispatcher-servlet'" id "org.springframework.web.context.WebApplicationContext:" displayName "Root WebApplicationContext" – user19937 Mar 07 '14 at 05:56
  • @user19937 Yes, that is normal. Your controllers and everything related to MVC should be in `dispatcher-servlet`. – Sotirios Delimanolis Mar 07 '14 at 05:57