14

I am trying to use Spring AOP with Spring MVC Controller. I have 3 aspects, and want the to be in specific order. In order to do this, I use Ordered interface and implement getOrder method:

@Aspect
@Component
public class LoggingAspect implements Ordered{

public int getOrder() {
System.out.println("Abra");
return 1;
}

Adviced class:

@Component
@Controller
public class HomeController {   

Pointcuts:

@Aspect
public class SystemArchitecture {

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void inHomeController(){}

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void loggable(){}

    @Pointcut("execution (* com.jajah.StorageManager.HomeController.*(..))")
    public void authenticated(){}

}

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <annotation-driven />
    <context:annotation-config /> 
    <aop:aspectj-autoproxy proxy-target-class="false"/>

    <beans:bean id="AuthenticationAspect" class="com.jajah.CommonAspects.SecurityAspects.OAuthAspect"/>
    <beans:bean id="ErrorHandlingAspect" class="com.jajah.StorageManager.Aspects.ErrorHandlingAspect"/>


    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <!-- <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />

    </beans:bean> -->

    <beans:bean name="homeController" class="com.jajah.StorageManager.HomeController">
        <beans:constructor-arg>     
            <beans:ref bean="CloudStorage"/>
        </beans:constructor-arg>
        <beans:constructor-arg>     
            <beans:ref bean="ConfigurationContainer"/>
        </beans:constructor-arg>
    </beans:bean>

    <beans:bean id="CloudStorage" name="CloudStorage"       class="com.jajah.StorageManager.CloudStorageProxy"      scope="singleton">
        <beans:constructor-arg>     
         <beans:ref bean="ConfigurationContainer"/>
        </beans:constructor-arg>
    </beans:bean>

    <beans:bean id ="ConfigurationContainer" class="com.jajah.StorageManager.ConfigurationContainer" scope="singleton"/>





</beans:beans>

The getOrder doesn't do the trick. I will appreciate any practical advice, or if you don't have the exact answer I will appreciate any theoretical knowledge about the Spring Proxy and the weaving mechanism.

I will post any Code/Configuration required upon demand. Thanks for reading.

Update: 1. I tried @Order(1) with same result. 2. I tried to move aspects to same package, it changed their order, but I still couldn't control it.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
Marat Asadurian
  • 593
  • 1
  • 6
  • 18

1 Answers1

25

You don't need to implement Ordered interface.

In Spring AOP you can do things much easier.

@Aspect
@Order(1)
public class AspectA
{
  @Before("............")
   public void doit() {}
}

@Aspect
@Order(2)
public class AspectB
{
  @Before(".............")
  public void doit() {}
} 

Update:

@Aspect
@Order(1)
public class SpringAspect {

    @Pointcut("within(com.vanilla.service.MyService+)")
    public void businessLogicMethods(){}

     @Around("businessLogicMethods()")
     public Object profile(ProceedingJoinPoint pjp) throws Throwable {
             System.out.println("running Advice #1");   
         Object output = pjp.proceed();
         return output;
     }
}

@Aspect
@Order(2)
public class SpringAspect2 {

    @Pointcut("within(com.vanilla.service.MyService+)")
    public void businessLogicMethods(){}

     @Around("businessLogicMethods()")
     public Object profile(ProceedingJoinPoint pjp) throws Throwable {
             System.out.println("running Advice #2");   
         Object output = pjp.proceed();
         return output;
     }
}

Now the application Context Configuration XML:

<context:annotation-config />
<aop:aspectj-autoproxy />

  <bean id="springAspect" class="com.vanilla.aspect.SpringAspect" />
    <bean id="springAspect2" class="com.vanilla.aspect.SpringAspect2" />

You need to enable AOP proxy by:

<aop:aspectj-autoproxy />

otherwise no advice will be activated.

Update 2:

I just make a research on this issue. @order annotation works only on Spring's based proxy AOP (Which I'm using in my example). Accoridng to documentation if you are using weaving you should use declare precedence option.

Update 3

  1. I don't see any advices in your code, just aspects and pointcuts.
  2. If your Advice classes are: x.y.z.SystemArchitecture

then you need to configure it at as

<bean id="systemArchitecture" class="x.y.z.SystemArchitecture" /> 

and I don't see it in your code.

  1. "execution (* com.jajah.StorageManager.HomeController.*(..))" what are you targeting on? Can you write it using words?

Anyway. Please drop me a message on facebook and I'll send you working example which does exactly what are you trying to do.

Tony
  • 5,972
  • 2
  • 39
  • 58
danny.lesnik
  • 18,479
  • 29
  • 135
  • 200
  • Actually I started with @Order annotation, but when it didn't worked I tried to implement Ordered interface and add System.out to verify that the proxy at least tries to order aspects. It didn't work. – Marat Asadurian Jan 29 '12 at 10:11
  • Then you have the problem with AOP configuration. Please see my updated code which runs perfect in my test environment. Don't forget that you need to configure POintcut and Advice type(Around, before or after). – danny.lesnik Jan 29 '12 at 10:31
  • I define pointcut, and aspects are working. The problem is just ordering. By the way I advice on controller, can it be the matter? Maybe you know some way to debug the weaving? – Marat Asadurian Jan 29 '12 at 11:34
  • Thanks for your feedback. I updated the original post with the adviced class (Controller) and Pointcuts. – Marat Asadurian Jan 29 '12 at 12:16
  • Please see my second update. hope it solves your issue. I'm always using AOP proxy so I forgot about second option :) – danny.lesnik Jan 29 '12 at 12:22
  • I have several questions: Why I can't use AOP proxy? What is the second option? Can you refer me to some documentation? – Marat Asadurian Jan 29 '12 at 12:51
  • You can use AOP Proxy, I wanted to ask you why are you not using Spring Proxy AOP. It is very simple to configure and use. will enable it. Regarding to second option I meant that you can use Spping AOP proxy and you can use weaving. Personally I prefer AOP proxy as it is "out of the box" Spring functionality. See my "Update 1" it shows how to use SPring AOP aspectj using proxy. – danny.lesnik Jan 29 '12 at 13:00
  • Actually I did exactly what you said, and I also preffer to use AOP Proxy. I will update my example with configuration – Marat Asadurian Jan 29 '12 at 13:08
  • The systemArchitecture class just defining general pointcuts. I'm targetting HomeController class. – Marat Asadurian Jan 29 '12 at 14:08
  • @MaratAsadurian, but where is your @Advice? Please drop me your email address via facebook or linkedin (i have a links in my profile page) and I'll send you working example. I beleive it will make all this easier. – danny.lesnik Jan 29 '12 at 14:14
  • I don't have an @Advice do I have to define it in order to use @Order? – Marat Asadurian Jan 29 '12 at 15:20
  • Yes you do need to define Advices. Please refer to section 7.2.4 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html – danny.lesnik Jan 29 '12 at 15:36
  • @danny.lesnik what are you on about? The "advice" is the `@Around` method. There's no such thing as an `@Advice`. – OrangeDog Apr 26 '16 at 16:46
  • Actually, using `@Order` may lead to unwanted rigidity - alternatively you could rely on the order of beans Spring discovers them. – jediz Apr 09 '18 at 15:06