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 |