user19937
user19937

Reputation: 587

Spring controller is not proxied

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

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

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

Related Questions