Jumping back on the aspects bandwagon (trying to explain something often helps
me to understand it):
Indirection, aka abstraction: You call a method on an interface, and the
recipient is determined at runtime, and may be at the end of several ‘middlemen’
who simply pass the message along. What AOP does for you is allow you to
dynamically compose a whole method call chain using reusable interceptors. So
calling setFoo() on something that appears to be a simple bean can actually take
a quick detour to your validation interceptor to check the syntax, then visit
the persistence interceptor, telling it that the field is dirty, before
returning. This is nothing that can’t already be done without AOP, but AOP (ie.
interceptors & extensions) appears to be much more flexible and reusable. Being
able to define your interceptor stack in a descriptor or programmatically means
you can substantially alter the behaviour of bits of your application while its
running, and the calling code still sees a simple ‘setFoo’ bean like interface.
And the possibilities for code reuse look huge.
Of course, I could be entirely wrong – I’m still trying to wrap my brain around