How does one implement an attribute-triggered advice in spring?

35 Views Asked by At

I am looking to use AOP to do some timing of calls. I want to statically decorate the methods with a custom attribute and then have the advice invoked (around) so that it takes a timestamp, makes the call and then takes a timestamp to determine the time span.

It seems simple but I cannot find how to do such a thing.

Details:

  • I am using Spring.NET (yes, it is dead but this is legacy code)

  • Here is my C# code extracted to remove proprietary details:

First of all, here is the Attribute. Pretty straightforward:

    [System.AttributeUsage(System.AttributeTargets.Method)]
    public class TimingAttribute : System.Attribute
    {
        public string TheAuditField { get; }
        public TimingAttribute(string auditField)
        {
            TheAuditField = auditField;
        }
    }

Second, the Advice class:

    public class AuditTimingAdvice : IMethodInterceptor
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (AuditTimingAdvice));
        public object Invoke(IMethodInvocation invocation)
        {
            Logger.Info("In AuditTimingAdvice");
            var result = invocation.Proceed();
            Logger.Info("After the call");
            return result;
        }
    }

Third, here is the XML for the service context for configuring Spring.NET

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  <description>Definitions of objects to be exported.</description>

  <object id="AuditTimingAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
    <property name="advice">
      <object type="SpringDotNetAopTestbed.AuditTimingAdvice, SpringDotNetAopTestbed"/>
    </property>
    <property name="attribute" value="SpringDotNetAopTestbed.TimingAttribute, SpringDotNetAopTestbed" />
  </object>

  <!-- Service -->
  <object id="TheServiceImpl" singleton="false" type="SpringDotNetAopTestbed.Service1, SpringDotNetAopTestbed" >
  </object>

  <object id="TheService" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
    <property name="target" ref="TheServiceImpl"/>
    <property name="interceptorNames">
      <list>
        <value>AuditTimingAdvice</value>
      </list>
    </property>
  </object>

</objects>

Finally, here is an example of how I would want to use the attribute:

    public class TargetExample
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (TargetExample));
        public void MethodOne()
        {
            Logger.Info("In Method one");
        }

        [Timing("full")]
        public void MethodTwo()
        {
            Logger.Info("In Method two");
        }
    }

The problem is that AuditTimingAdvice.Invoke() never gets entered.

0

There are 0 best solutions below