Reputation: 587
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
Upvotes: 0
Views: 319
Reputation: 279970
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.
Upvotes: 1