23

I ams using Spring 2.5.6, asm 1.5.3, aspectjrt/aspectjweaver 1.6.1, cglib 2.1_3 In my Web based Spring application I have following class:

package uk.co.txttools.aspects;

@Aspect
public class LoggingAspect {
    @Before("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.set*(..))")
    public void setLoggingAdvice(){
        System.out.println("********************************* Advice run..... set mothod called....");
    }

    @AfterThrowing("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.onSubmit(..) throws java.lang.Exception)")
    public void hadleException(){
       System.out.println("================= PreviewMessageController =========== ON SUBMIT Exception Throwen ==================");
    }

    @Before("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.onSubmit(..) throws java.lang.Exception)")
    public void OnSubmitAspect(){
        System.out.println("================= PreviewMessageController =========== ON SUBMIT CALLED ==================");
    }
}

I have one Controller:uk.co.txttools.web.controller.compose.PreviewMessageController which hasonSubmit()method, which get called from web page. I have separateapplicationContext.xml` file.

My springapp-servlet.xml(which is used in web.xml file with org.springframework.web.servlet.DispatcherServlet) file looks like this:

<?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:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<aop:aspectj-autoproxy proxy-target-class="true" />

<bean id="loggingAspect" class="uk.co.txttools.aspects.LoggingAspect" />
.
.

Below in same xml file PreviewMessageController get initialize which means my Controller and Aspect live is same container.

I don't get any exception while running application but my aspect class LoggingAspect never get called. I'm not sure what is that missing or I'm doing wrong. Please help me..

Thanks

Kristijan Iliev
  • 4,901
  • 10
  • 28
  • 47
bhavin
  • 337
  • 1
  • 2
  • 9

7 Answers7

44

I'm not sure if I did it properly but for me what solved it was adding @Component to the "Aspect'ed" class -

@Aspect
@Component
public class PerformanceLogger {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("within(com.something.rest.service..*)")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        long end = System.currentTimeMillis();
        logger.debug(pjp.getSignature().toShortString() + " Finish: " + (end - start) + "ms");
        return retVal;
    }
}

(And just to close the loop - if you are using annotation based, don't forget adding @EnableAspectJAutoProxy to your Config class.

@EnableAspectJAutoProxy
Arpit Aggarwal
  • 27,626
  • 16
  • 90
  • 108
baraka
  • 807
  • 8
  • 16
  • 2
    I wonder why this is not clearer in the documentation. It fixed my problem as well. – idipous Jun 16 '17 at 16:57
  • 6
    @idipous I believe that the documentation that clears this out is [link](https://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-ataspectj): _You may register aspect classes as regular beans in your Spring XML configuration, or autodetect them through classpath scanning - just like any other Spring-managed bean. However, note that the @ Aspect annotation is not sufficient for autodetection in the classpath: For that purpose, you need to add a separate @ Component annotation..._ – Victor Jan 04 '19 at 10:03
  • 1
    @Arpit In short, @ Aspect is not a Spring annotation but an AspectJ one. That is why you need to mark the aspect you create as a Spring component by adding Spring specific annotations. – Victor Jan 04 '19 at 10:04
  • 1
    @Inject is not a Spring specific annotation either but spring recognizes it. They could (really should if you ask me) have gone the extra-mile of having (@)Aspect Behave as a (@)Compenent once you load the spring-aop or spring-aspects lib ... – Ar3s Nov 02 '20 at 10:59
12

For those who opted for JavaConfig, you can declare your Aspect as a bean and add the @EnableAspectJAutoProxy annotation to turn on auto-proxying :

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class MyConfig {
    @Bean
    public LoggingAspect loggingAspect(){
        return new LoggingAspect();
    }
}
Zakaria
  • 14,892
  • 22
  • 84
  • 125
5

Finally SOLVED it.

I think I was missing aspectj-maven-plugin. It required for spring to weaving of aspects. None tutorial provide this information though. Added following to my pom.xml.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.0</version>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.6.1</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <outxml>true</outxml>
        <verbose>true</verbose>
        <showWeaveInfo>true</showWeaveInfo>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
        </aspectLibraries>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>

Thanks guys

Kristijan Iliev
  • 4,901
  • 10
  • 28
  • 47
bhavin
  • 337
  • 1
  • 2
  • 9
  • 7
    No, that plugin is not needed for weaving Spring AOP aspects, only if you want to use full AspectJ load-time weaving or compile-time weaving. What you did was to use CTW. The real fix would have been to fix your Spring AOP configuration. – kriegaex Mar 04 '17 at 12:20
1

If you havent tried already...try the xml based spring-aop configuration as follows:

    <aop:config>
    <aop:aspect ref="loggingAspect">
        <aop:pointcut expression="execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.set*(..))" id="previewMessageControllerSetters"/>
        <aop:before method="setLoggingAdvice" pointcut-ref="previewMessageControllerSetters"/>

         // set other 2 pointcuts similarly....
        </aop:aspect>       
    </aop:config>
    <bean id="loggingAspect" class="uk.co.txttools.aspects.LoggingAspect" />
Vikram
  • 4,162
  • 8
  • 43
  • 65
  • Thanks for your reply Vikram but I have tried that too, even XML based configuration doesn't work. I think Cglib is not be able to generate proxy for me. Any advise in that ???? – bhavin Jan 24 '13 at 09:08
  • @bhavin.patel I think what you had done with `proxy-target-class="true"` should have served your purpose...I think the problem may be with aspectjrt and aspectjweaver jar files...I use Spring 3.0 with aspectjrt and aspectweaver version 1.6.8. If your project is Maven based and if you dont mind upgrading to Spring 3.0 you could quickly swap and check.. – Vikram Jan 24 '13 at 15:30
  • or even better if you can swap out cglib dependencies in your code and check if it works for Spring 2.5/ AspectJ 1.5.3. If you are using Spring IDE then you would have markers on all your methods that would be advised... this way atleast you can get some idea if your aspects are even getting compiled... – Vikram Jan 24 '13 at 15:38
1

Only to make the list of possible answers complete:

To me it looks like you are missing the following dependency in your maven pom.xml:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>2.5.6</version>
</dependency>
PowerStat
  • 3,757
  • 8
  • 32
  • 57
0

Try this in your config file:

<aop:aspectj-autoproxy proxy-target-class="true">
     <aop:include name="loggingAspect"/>
</aop:aspectj-autoproxy>
Vikram
  • 4,162
  • 8
  • 43
  • 65
  • It still doesn't work, I still get no exception but my aspect never get called. I think my Controller is not getting proxied hence AOP won't work. I thought having cglib in path and have would solve this issue but not sure what's missing ? – bhavin Jan 22 '13 at 16:24
0

I had this issue and as I didn't see the reason for that I'm mentioning it. My problem was related to the component scan. There was a config class like this:

@ComponentScan(basePackages = {
    "com.example.web.controller",
    "com.example.service",
    "com.example.repository"})

And the aspect class was located in the log package and needed to add it to the @ComponentScan.

Payam Soudachi
  • 301
  • 3
  • 5