7

I'm working on a project that uses the Java (not xml) flavour of Spring configuration for wiring up dependencies. It also has profiling logic that should be weaved via AspectJ onto the desired methods (via annotations). The setup is working and I can see classes from my desired package being weaved and profiling information being logged out of them.

The problem is that weaving does not work for @Bean classes. I've enabled debug in aop.xml via:

<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">

And I can see classes in my desired package being weaved, but not the beans in the configuration. If I instantiate the classes directly (not inject them) weaving works.

Unfortunately, I can't post real code here, but here's a dumbed down example:

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
public class MySpringConfig {
    @Bean
    AnnotatedClass1 annotatedClass1() {
        return new AnnotatedClass1(new AnnotatedClass2());
    }
}

AnnotatedClass1 and AnnotatedClass2 live in the same package and weaving works on the one instantiated directly and not the one returned by the bean.

I've searched through the Spring AOP docs but I can't seem to find anything related to this. There is some magic you need to do for auto-proxying and some limitations for SpringAOP but load time weaving should just work as far as I can tell - I've tried on private methods for example and it worked.

Alex Ciminian
  • 11,398
  • 15
  • 60
  • 94

1 Answers1

3

The problem was the return type - if I do:

@Bean
Object annotatedClass1() {
    return new AnnotatedClass1(new AnnotatedClass2());
} 

the weaving starts to work for the bean as well. My initial assumption was that it has something to do with Spring caching the bean and not using the weaved version, but this didn’t make sense because:

  • load time weaving is supposed to act at, well… class load time :). Then, it doesn’t matter what the method returns, the class should have the aspects.
  • I’ve actually checked the debug output for both Spring and AspectJ and no mention of my class so it must have been ignored somehow.

This is the first time I’ve used this stuff, so I might be misunderstanding things. If anyone can explain why the return type of the @Bean method has anything to do with weaving I’d be happy to accept your answer instead of this one.

Alex Ciminian
  • 11,398
  • 15
  • 60
  • 94
  • 4
    Loadtime weaving, as the name suggest, works on loading classes. Now when the return time is `AnnotatedClass1` this will result in eagerly loading that class as well, when it is `Object` the loading is deferred until it is actual needed. Now due to the eager loading the class is already loaded before the load time-weaver can do its work. – M. Deinum May 03 '14 at 13:35
  • Can you provide some reference for above argument. I searched on google but seems I am not good in googling :-) – SIGSTP May 03 '14 at 15:12
  • 1
    Wow. I spent a good day hacking away at my config. Could not understand why only my non-spring classed were being weaved. This totally makes sense. And, why it makes sense that in XML config - this issues would not be seen. Thank you! – Michael Andrews Oct 31 '14 at 12:05
  • If I return object then spring auto proxy stops working :( Looks like you have to provide 2 different context definition depending on auto proxy or LTW. – Alvin Apr 14 '15 at 01:22