ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Separation of Concerns in Web Service Implementations
Pages: 1, 2, 3, 4

Business Logic Implementation and Configuration

We'll start off by explaining the implementation and configuration for the business logic classes, since they are the simplest. See the source for the AccountMgr interface and the AccountMgrImpl class in the downloadable sample code. As you can see from the source, the implementation doesn't actually do anything, so we can keep things simple since this article's not about how to write code for transferring funds.



Below is a fragment of the Spring configuration file (the entire configuration file is available in the Resources section) showing how we've configured the Spring beans for the business logic so that we can use Spring's AOP facilities. The first bean entry simply sets up a bean for our AccountMgrImpl class. The second bean entry is how we get all of the AOP proxy magic we discussed earlier to work. We set up a bean with id accountMgr that will be obtained from the ProxyFactoryBean. When the FundsTransferServiceSoapBindingImpl class asks Spring for the bean with this id, the ProxyFactoryBean will return an instance of the AOP proxy object. We configure it to implement our AccountMgr interface so that client programs think they're just working with a business logic object. With the second property named interceptorNames, we set it up such that a bean called securityInterceptor (which will be explained later) can intercept method invocations to perform security checks. This allows us to plug in the Acegi security mechanisms without any dependencies in our business logic code. Finally, we set the target to the accountMgrTarget bean so that the method invocations will eventually be propagated to our actual business logic class, AccountMgrImpl.

<beans>
  <bean id="accountMgrTarget"
    class="com.mybank.bizlogic.AccountMgrImpl"/>
  . . .
  <bean id="accountMgr"
    class="org.springframework.aop.framework.
    ProxyFactoryBean">
    <property name="proxyInterfaces">
      <list>
        <value>
          com.mybank.bizlogic.AccountMgr
        </value>
      </list>
    </property>
    <property name="interceptorNames">
      <list>
        <value>
          securityInterceptor
        </value>
      </list>
    </property>
    <property name="target">
      <ref bean="accountMgrTarget"/>
    </property>
  </bean>
  . . .
</beans>

Web Service Implementation and Configuration

The FundsTransferServiceSoapBindingImpl class is the web service implementation. See the source for it in the downloadable sample code. The skeleton for this class is generated by Axis, and we just fill in the methods to provide the implementation. Notice that this class extends ServletEndpointSupport. This is a convenience class provided by Spring that can be used for JAX-RPC web service implementations to obtain a reference to the Spring application context. By extending this class, the FundsTransferServiceSoapBindingImpl class can access the Spring context to obtain a reference to the accountMgr bean described earlier. Since the FundsTransferServiceSoapBindingImpl class is managed by Axis, we can't use Spring's dependency injection facilities to automatically get a reference to that bean. Thus, we have to do it explicitly in the onInit() method. Unfortunately, this adds some dependencies in this class to Spring-specific classes. Oh, well--that's a small price to pay to be able take advantage of the benefits of using Spring and Acegi. Notice that in the actual method transferFunds(), the code just delegates to the accountMgr bean.

In the Axis configuration files (deploy.wsdd and server-config.wsdd), we'll need to make sure that the implementation class for the service is set to this class, FundsTransferServiceSoapBindingImpl, and not the other skeleton class (FundsTransferServiceSoapBindingSkeleton) that is generated by Axis. To get Spring to work properly in the same web application as Axis, we'll need to add the following entries to the web.xml file. The context-param entry specifies where the Spring configuration file is located. The listener entry sets it up so that the Spring configuration and context is loaded up at start up.

<web-app>
  <context-param>
    <param-name>
      contextConfigLocation
    </param-name>
    <param-value>
      /WEB-INF/spring-config.xml
    </param-value>
  </context-param>

  <listener>
    <listener-class>
      org.springframework.web.context.
      ContextLoaderListener
    </listener-class>
  </listener>
. . .
</web-app>

Pages: 1, 2, 3, 4

Next Pagearrow