This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

This is a known problem when using the decorator pattern (which Spring AOP uses); the class that is being decorated has no knowledge of the decorator. If you are using the ProxyFactoryBean you can call setExposeProxy to true and then access it via http://www.springframework.org/docs/...opContext.html

But the basic idea is: Spring AOP doesn't support interception from a function in the same class. It is definitely under this AOP category.

As I mentioned in my reply a couple of replies ago, Spring AOP *does* support interception from a function in the same class, you just need to do a bit more to get it to work.

The fundamental problem is that Spring uses a decorator, in the form of a runtime generated proxy to execute the interceptors (transactional, logging etc.), this effectively means that there are two classes, the generated proxy and your "target" class. The target class has no knowledge of the proxied class, and thus when it calls methods on itself it is completely bypassing the proxy. You can make the target class aware of the proxy by using the AopContext class (http://www.springframework.org/docs/...opContext.html).

So when clients call myClass.myFirstMethod() they are actually talking to the runtime generated proxy, however, if myFirstMethod() calls mySecondMethod() the call to mySecondMethod will *not* go through the proxy.

PLEASE(!!!) do not take the above code too seriously as Spring offers far more functionality, but hopefully it demonstrates the point.

Also note that this is completely irrelevant if you are using compile time weaving which doesn't use a decorator/proxy but modifies the byte code directly.

Comment

Thanks Colin to clear things up. But I think the power of Spring is its unintrusiveness. If I make class aware of AOPContext, I'd rather make function call directly, i.e. call log4j to log the message instead of letting AOP do it.

My intention is: write program as independent as possible. When I introduce AOPContext into business logic layer, it will prevent me to easily port to other situations.

However, thanks for explaining the details, that make things clear -- especially from a Spring team member, I really appreciated.

My intention is: write program as independent as possible. When I introduce AOPContext into business logic layer, it will prevent me to easily port to other situations.

This is a very good point.

There are a number of more elegant solutions that I can think of, but I haven't really got time ATM to go into detail.

Essentially, instead of calling this.doSomething() call getThis().doSomething() and then provide a setThis(MyBean). You could then write a BeanPostProcessor to find all beans that implement a setThis and inject the bean back into itself.

Just as addition to the solution described by Colin, see this thread. It also contains an example for the application context.

Regards,
Andreas

Hey Andreas! You know what they say, "great minds think alike", but then they also say "fools seldom differ". Not sure which category I fall in

I would suggest that my BeanPostProcessor solution is a little more elegant (and safer) than implementing FactoryBeanAware (or ApplicationContextAware) and InitialisingBean simply because if the bean is a prototype you then setThis will be called with a different instance, which is absolutely what you do not want

Comment

Hey Andreas! You know what they say, "great minds think alike", but then they also say "fools seldom differ". Not sure which category I fall in

...or I

Originally posted by yatesco

I would suggest that my BeanPostProcessor solution is a little more elegant (and safer) than implementing FactoryBeanAware (or ApplicationContextAware) and InitialisingBean simply because if the bean is a prototype you then setThis will be called with a different instance, which is absolutely what you do not want

I agree. Only wondering, where I suggested implementing FactoryBeanAware? I guess you refer to my explicit usage of ProxyFactoryBean. In that case, yes, for prototypes it would be a problem.