|
From: Rod J. <rod...@in...> - 2003-02-13 19:11:30
|
Chris,
The interceptors get invoked in order before each method call on the target
object. Actually, interceptors are chained, so that the head of the
interceptor chain gets to do processing before and after subsequent
interceptors are invoked--hence before and after the ultimate method call.
Imagine that debugInterceptor and invokerInterceptor are interceptors, that
the proxy implements interface ITestBean and TestBean is the target
implementation.
The control flow will be:
client calls ITestBean method -> AopProxy (dynamic proxy) ->
debugInterceptor -> invokerInterceptor -> TestBean ->
invokerInterceptor ->debugInterceptor -> client
Each interceptor has access to an com.interface21.aop.Invocation object that
contains information about the method signature, attributes and
"resources"--objects added to the invocation by previous interceptors in the
chain.
Let's look at how this is set up in the aoproxy_chain2.xml file from the
test suite.
Interceptors and target objects are set up as beans (what else). The
AopProxy is also created via a special bean definition.
<beans>
Interceptors are simply bean definitions, and must implement
com.interface21.aop.Interceptor:
<bean name="debugInterceptor" class="com.interface21.aop.DebugInterceptor"
singleton="false">
</bean>
<bean name="invokerInterceptor"
class="com.interface21.aop.InvokerInterceptor" singleton="false">
<property name="target" beanRef="true">test</property>
</bean>
If we use the invoker interceptor, it will need to use reflection to invoke
a target, so in this case we need an actual implementation of ITestBean:
<bean name="test" class="com.interface21.beans.TestBean">
<property name="name">custom</property>
<property name="age">666</property>
</bean>
When we set up the AopProxy we specify
* the interfaces it must "implement" (only one in this case)
* the debug interceptor names: the beans will be configured in the order
specified. this makes it very easy to change interceptor ordering
* attributes that set interceptor behaviour. These are per method. NB: I'm
considering overhauling the attribute implementation, which is not complete
anyway. I'm interested in the .NET approach in which attributes are objects.
Maybe they could also be bean references.
Attributes, for example, would govern the behaviour of a transaction
interceptor.
<bean name="aoproxy"
definitionClass="com.interface21.aop.AopProxyBeanDefinition"
>
<customDefinition
property="proxyInterfaces">com.interface21.beans.ITestBean</customDefinition
>
<customDefinition
property="interceptors">debugInterceptor,invokerInterceptor</customDefinitio
n>
<customDefinition property="attributes">
setAge=txAge
getName=txName,txName2
</customDefinition>
</bean>
</beans>
Now we can access the proxy like any other implementation of the ITestBean
interface. The use of AOP is transparent to client code.
ITestBean t = (ITestBean) beanFactory.getBean("aoproxy");
Cross-cutting functionality can be added to all proxied method invocations,
through the interceptor's behaviour.
Regards,
Rod
> Rod,
>
> I have been reviewing your AOP code and wonder if you could provide a
brief
> explanation on how it works. I'm not sure when the interceptors get
invoked
> and how you can control their timing. Also are the interceptors the
> mechanism to add, "cross cutting functionality"? Please explain.
>
> Regards,
>
> Chris Axe
|