views:

69

answers:

3

Hi guys,

I'm having a bit of a problem defining my aspects. I've got a bunch of entities that I'd like to profile the get-methods in, so I've written the following pointcut and method

@Pointcut("execution(* tld.myproject.data.entities.*.get*()")
public void getEntityProperty() {}

@Around("getEntityProperty()")
public Object profileGetEntityProperty(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();
    String name = pjp.getSignature().getName();
    Object output = pjp.proceed();
    long elapsedTime = System.currentTimeMillis() - start;
    if(elapsedTime > 100)
        System.err.println("profileGetEntityProperty: Entity method " + name + " execution time: " + elapsedTime + " ms.");
    return output;
}

I've got weaving turned on in my configuration, and aspects weaving into the business layer work just fine. Is my pointcut correctly written? Or is there something about entities that make them non-weavable? (my entity is prefixed with @Entity before the class definition)

Cheers

Nik

+1  A: 

Yes, there is. The entities are created by you, using the new operator, and hence they are not part of the spring context.

If you want to use this, you'd need to enable weaving (I prefer load-time via <context:load-time-weaver/>), and to annotate your entity classes with @Configurable.

I, personally, wouldn't prefer this practice. Alas, there aren't any alternatives that are so generic. If your persistence provider is Hibernate, you can create a custom proxy of your entities - see here, but this is even more awkward.

Bozho
Thanks for the tip, I read section 7.8.1 in http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-aspectj-programmatic after your tip, and @Configurable seems marvelous. What is it about this practice you don't like?
niklassaers
it's more of a personal preference, but what happens is "dark magic behind the scene", and it doesn't feel OK to me. Although I can't claim there are any sufficient drawbacks ;)
Bozho
Ok, so I've added `@Configurable(preConstruction=true)` to my entities and set `<context:spring-configured/>` in my config, but still the aspect isn't being woven in. Any tips on what I've missed? PS, my entities are created through Hibernate via `DAO.getSession().createCriteria(MyEntity.class).list()`
niklassaers
`<context:load-time-weaver/>`
Bozho
Why do you say load-time weaving? I haven't seen anything that doesn't work with compile-time weaving too. As I understand it, he only needs AspectJ, the weaving alternatives are up to him.
Espen
you are right. Again my personal preference of load-time vs compile-time weaving has influenced the answer :)
Bozho
+4  A: 

Hello Nik

You're only a parenthesis away actually!

@Pointcut("execution(* tld.myproject.data.entities..get())")


If you're using Eclipse, I will recommend developing with AspectJ compile-time weaving. It's the simplest way.

With the AJDT plugin, you get lots of help! I just pasted in your pointcut and got an compilation error. Added a parenthesis and it worked!

Screenshot of visual support with the AJDT plugin:

alt text

The orange arrow to the left of the getHello() method indicates that is's advised by an around advice. See here for a larger example.

Espen
good catch (+1). Do you know AJDT plugin can validate these expressions at compile time?
Bozho
Hi Espen, I'll try out the AJDT plugin. Does that work well with Spring? I was under the impression Spring does its own weaving?
niklassaers
@Bozho: Thanks! The error message I got from the AJDT plugin: `Syntax error on token "execution(* entity..get()", ")" expected`
Espen
@niklassaers: The AJDT plugin works very well with Spring! The easiest alternative is to download [SpringSource Tool Suite](http://www.springsource.com/products/sts "SpringSource Tool Suite") that has the AJDT plugin bundled. With this plugin package, you can get the same tool help for Spring AOP as well.
Espen
So I can mix and match compile-time weaving and load-time weaving? Wow, I didn't know that. This one is an obvious case for compile-time weaving, so I'll give that a whirl. :-) Thanks for the link to your blogpost, I'll follow your recipe (and learn about the AJDT plugin) :-)
niklassaers
@niklassaers: No, you can't mix AspectJ load and compile-time weaving. But you can mix AspectJ with Spring AOP. For example to use AspectJ on your `get*()` method pointcut and use Spring AOP for transaction handling.
Espen
Perfect, this is the one I ended up using :-) Now well integrated into both Eclipse and maven and my tests :-) I still have to learn a bit about separating the compile-time weaving from the load-time weaving, but I'm sure the docs'll help me on that :-)
niklassaers
A: 

Just a note that @Configurable works with compile-time weaving. The drawback to autowiring entities via @Configurable is that they don't 'seem' to work when retrieving said entities from a database via Hibernate. Via a 'new' invocation, yes. But just recently, given a very weird request to do persistence from an entity, a unit test using 'new' worked perfectly, yet hibernate (or ehcache) loaded-entities resulted in NPEs for the autowired property. It was late at night; so you may wish to do some testing yourself.:) Just passing along my recent experience. Hope it helps.

Mike Funk