Skip to main content

Spring.net Application Framework - Part One

Our new project will use Spring.net 2.0, hence, I started learning how to use it. Need to create a prototype implementation for team.

How to install it?
Like other .net library, you just copy the dll files
(Spring.Services.dll, Spring.Aop.dll and Spring.Core, Common.Logging.dll and the counterpart xmls files to
 to your project and do the configuration.

How to use it?
Take Spring Integration with WCF(Windows Communication Foundation) as an example,


Step 1: define the Services
 namespace Spring.WcfQuickStart
{
    [Serializable]
    public class BinaryOperationArgs
    {
        private double x;
        private double y;

        public BinaryOperationArgs(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

        public double X
        {
            get { return x; }
        }

        public double Y
        {
            get { return y; }
        }
    }

    [Serializable]
    public class OperationResult
    {
        private double result;

        public OperationResult(double result)
        {
            this.result = result;
        }

        public double Result
        {
            get { return result; }
        }
    }

    [ServiceContract(Namespace = "http://Spring.WcfQuickStart")]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
        [OperationContract]
        string GetName();
        [OperationContract]
        OperationResult Power(BinaryOperationArgs args);
    }
}


Step 2: Implementation
 namespace Spring.WcfQuickStart
{
    public class CalculatorService : ICalculator
    {
       // the value will be injected in weaving time
        private int sleepInSeconds;

        public int SleepInSeconds
        {
            get { return sleepInSeconds; }
            set { sleepInSeconds = value; }
        }

        public double Add(double n1, double n2)
        {
            Thread.Sleep(sleepInSeconds * 1000);
            return n1 + n2;
        }

        public double Subtract(double n1, double n2)
        {
            Thread.Sleep(sleepInSeconds * 1000);
            return n1 - n2;

        }

        public double Multiply(double n1, double n2)
        {
            Thread.Sleep(sleepInSeconds * 1000);
            return n1 * n2;

        }

        public double Divide(double n1, double n2)
        {
            Thread.Sleep(sleepInSeconds * 1000);
            return n1 / n2;

        }

        public OperationResult Power(BinaryOperationArgs args)
        {
            // do something
            return new OperationResult(Math.Pow(args.X, args.Y));
        }

        public string GetName()
        {
            Thread.Sleep(SleepInSeconds * 1000);
            return "WebApp Calculator";
        }
    }
}

Step 4: Define the IMethodInterceptor
public class SimplePerformanceInterceptor : IMethodInterceptor
    {
        private string prefix = "Invocation took";

        public string Prefix
        {
            get { return prefix; }
            set { prefix = value; }
        }

        #region IMethodInterceptor Members

// Summary:
        //     Implement this method to perform extra treatments before and after the call
        //     to the supplied invocation.
        //
        // Parameters:
        //   invocation:
        //     The method invocation that is being intercepted.
        public object Invoke(IMethodInvocation invocation)
        {
            DateTime start = DateTime.Now;
            try
            {
                return invocation.Proceed();
            }
            finally
            {
                DateTime stop = DateTime.Now;
                TimeSpan time = stop - start;
                Console.Out.WriteLine(Prefix + " " + time);
            }
        }

        #endregion
    }

Step 3: AOP codes
public class SimplePerformanceInterceptor : IMethodInterceptor
    {
        private string prefix = "Invocation took";

        public string Prefix
        {
            get { return prefix; }
            set { prefix = value; }
        }

        #region IMethodInterceptor Members

        /// <summary>
        /// IMethodInvocation
        // Summary:
        //     Gets the method invocation that is to be invoked.
        //
        // Remarks:
        //      This property is a friendly implementation of the AopAlliance.Intercept.IJoinpoint.StaticPart
        //     property.  It should be used in preference to the AopAlliance.Intercept.IJoinpoint.StaticPart
        //     property because it provides immediate access to the underlying method without
        //     the need to resort to a cast.
        // MethodInfo Method { get; }
        //
        // Summary:
        //     Gets the proxy object for the invocation.
        // object Proxy { get; }
        //
        // Summary:
        //     Gets the target object for the invocation.
        // object Target { get; }
        //
        // Summary:
        //     Gets the type of the target object.
        // Type TargetType { get; }
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public object Invoke(IMethodInvocation invocation)
        {
            DateTime start = DateTime.Now;
            try
            {   // deal with something about invocation
   //...
                return invocation.Proceed();
            }
            finally
            {
                DateTime stop = DateTime.Now;
                TimeSpan time = stop - start;
                Console.Out.WriteLine(Prefix + " " + time);
            }
        }

        #endregion
    }

Step 4: Configuration - web.config
<configuration>
  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
    </sectionGroup>
  </configSections>

  <!-- Spring Context Configuration -->
  <spring>
 
    <context>
      <resource uri="config://spring/objects"/>
    </context>
 
    <objects xmlns="http://www.springframework.net"
             xmlns:aop="http://www.springframework.net/aop">
      <!-- Service definition -->
      <object id="calculator" type="Spring.WcfQuickStart.CalculatorService, Spring.WcfQuickStart.ServerWeb"
              singleton="false">

<!-- the value to be injected when weaved -->
        <property name="SleepInSeconds" value="1"/>
      </object>

      <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
        <property name="pattern" value="^Spring.WcfQuickStart.*"/>
      </object>

      <object id="perfAdvice" type="Spring.WcfQuickStart.SimplePerformanceInterceptor, Spring.WcfQuickStart.ServerWeb">
       <!-- the value of Prefix will be injected in running time
        <property name="Prefix" value="Service Layer Performance"/>
      </object>

     <!-- weave the advices to each crosscutting around the pointcuts,
      <aop:config>
        <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice"/>
      </aop:config>

    </objects>

  </spring>

  <!-- WCF Service Configuration -->
  <system.serviceModel>
    <services>
      <service name="calculator" behaviorConfiguration="DefaultBehavior">
        <endpoint address="" binding="basicHttpBinding" contract="Spring.WcfQuickStart.ICalculator"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

  <appSettings/>

  <connectionStrings/>

  <system.web>
    <!--
            Set compilation debug="true" to insert debugging
            symbols into the compiled page. Because this
            affects performance, set this value to true only
            during development.
        -->
    <compilation debug="true">

    </compilation>
    <!--
            The <authentication> section enables configuration
            of the security authentication mode used by
            ASP.NET to identify an incoming user.
        -->
    <authentication mode="Windows"/>
    <!--
            The <customErrors> section enables configuration
            of what to do if/when an unhandled error occurs
            during the execution of a request. Specifically,
            it enables developers to configure html error pages
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
  </system.web>
</configuration>

 step





Comments

Popular posts from this blog

Quicksort implementation by using Java

 source: http://www.algolist.net/Algorithms/Sorting/Quicksort. The divide-and-conquer strategy is used in quicksort. Below the recursion step is described: 1st: Choose a pivot value. We take the value of the middle element as pivot value, but it can be any value(e.g. some people would like to pick the first element and do the exchange in the end) 2nd: Partition. Rearrange elements in such a way, that all elements which are lesser than the pivot go to the left part of the array and all elements greater than the pivot, go to the right part of the array. Values equal to the pivot can stay in any part of the array. Apply quicksort algorithm recursively to the left and the right parts - the previous pivot element excluded! Partition algorithm in detail: There are two indices i and j and at the very beginning of the partition algorithm i points to the first element in the array and j points to the last one. Then algorithm moves i forward, until an element with value greater or equal

Live - solving the jasper report out of memory and high cpu usage problems

I still can not find the solution. So I summary all the things and tell my boss about it. If any one knows the solution, please let me know. Symptom: 1.        The JVM became Out of memory when creating big consumption report 2.        Those JRTemplateElement-instances is still there occupied even if I logged out the system Reason:         1. There is a large number of JRTemplateElement-instances cached in the memory 2.     The clearobjects() method in ReportThread class has not been triggered when logging out Action I tried:      About the Virtualizer: 1.     Replacing the JRSwapFileVirtualizer with JRFileVirtualizer 2.     Not use any FileVirtualizer for cache the report in the hard disk Result: The japserreport still creating the a large number of JRTemplateElement-instances in the memory        About the work around below,      I tried: item 3(in below work around list) – result: it helps to reduce  the size of the JRTemplateElement Object        

Stretch a row if data overflows in jasper reports

It is very common that some columns of the report need to stretch to show all the content in that column. But  if you just specify the property " stretch with overflow' to that column(we called text field in jasper report world) , it will just stretch that column and won't change other columns, so the row could be ridiculous. Haven't find the solution from internet yet. So I just review the properties in iReport one by one and find two useful properties(the bold  highlighted in example below) which resolve the problems.   example: <band height="20" splitType="Stretch" > <textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="true"> <reportElement stretchType="RelativeToTallestObject" mode="Opaque" x="192" y="0" width="183" height="20"/> <box leftPadding="2"> <pen lineWidth="0.25"/>