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

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"/> …

JasperReports - Configuration Reference

Spring - Operations with jdbcTemplate

This class manages all the database communication and exception handling using a java.sql.Connection that is obtained from the provided DataSource. JdbcTemplate is a stateless and threadsafe class and you can safely instantiate a single instance to be used for each DAO.


Use of Callback Methods
JdbcTemplate is based on a template style of programming common to many other parts of Spring. Some method calls are handled entirely by the JdbcTemplate, while others require the calling class to provide callback methods that contain the implementation for parts of the JDBC workflow. This is another form of Inversion of Control. Your application code hands over the responsibility of managing the database access to the template class. The template class in turn calls back to your application code when it needs some detail processing filled in. These callback methods are allowed to throw a java.sql.SQLException, since the framework will be able to catch this exception and use its built-in excepti…