Section 6.2. Configuring a Service

team bbl


6.2. Configuring a Service

You've built an audit service that will help you keep track of changes in the application. Now, you need to attach the service to your code. You'll configure the service in this lab.

6.2.1. How do I do that?

The interceptor strategy uses three objects: the target (our façade), a proxy object that Spring creates for you, and an interceptor, which you'll build. Recall that you've got to do three things:

  1. Configure the advice.

  2. Configure the advisor, including a target object, target methods, and the advice.

  3. Configure the target object.

  4. Configure the proxy to use the advisor.

The target object already exists: our façade. The proxy already exists, because you used it for transactions. You need to configure the advice and add it to your proxy. Example 6-3 shows the changes to the context.

Example 6-3. RentABike-servlet.xml
<beans>       <bean      >       <property name="sessionFactory">          <ref local="sessionFactory"/>       </property>    </bean>    <bean   >       <property name="transactionManager">          <ref local="transactionManager"/>       </property>       <property name="transactionAttributeSource">          <value>             com.springbook.HibernateRentABike.save*=PROPAGATION_REQUIRED          </value>       </property>    </bean>    <bean         >       <property name="factory">          <ref local="sessionFactory"/>       </property>    </bean>    <bean  >       <property name="storeName">          <value>Bruce's Bikes</value>       </property>       <property name="sessionFactory">          <ref local="sessionFactory"/>       </property>    </bean>    <bean         >       <property name="proxyInterfaces">          <value>com.springbook.RentABike</value>       </property>       <property name="interceptorNames">          <list>             <value>loggingBeforeInterceptor</value>             <value>transactionInterceptor</value>             <value>rentaBikeTarget</value>          </list>       </property>    </bean>    <!-- etc. --> </beans> <bean  >    <property name="driverClassName">       <value>com.mysql.jdbc.Driver</value>    </property>    <property name="url">       <value>jdbc:mysql://localhost/bikestore</value>    </property>    <property name="username"><value>bikestore</value></property> </bean>

Now, you can let it rip. Notice that you get an audit trail whenever you change any record.

6.2.2. What just happened?

So far, most Java developers use programmatic servicesyou load them and access them explicitly. Spring also allows declarative servicesyou specify them in configuration rather than codewith proxy objects. A proxy object stands in for a target object, forwarding calls to the target after providing its service. The proxy and its target have the same interface. CORBA used proxies to do distributed communication, without forcing us to create any code for distribution: the intelligence was in the proxy. With AOP, the job of the proxy is to apply advice to remote objects.

Our example uses simple before advice. Now, let's look at around advice, the most complex model. If you understand the most advanced flow, the others should be easy. Figure 6-2 shows how advice works in Spring. The BikeDAO is the target object. It has the business code. To configure an interceptor, you specify a proxy. The proxy maintains a chain of interceptors. An object calls a method on the proxy instead of the target object. When you call a method on the proxy or fire an exception, the proxy calls the first interceptor in the chain. Each interceptor does its work and then invokes the next interceptor in the chain. The last interceptor invokes the target method or exception. After the target does its work, the interceptors just return right back down the chain.

Figure 6-2. Spring attaches services to POJOs through proxies that call an interceptor chain


In this example, you configured a proxy on a target object. You told the proxy to apply your interceptor to any method in the target, but you could have just as easily specified a subset of the methods with a regular expression. Example 6-4 is the same advice, coded as an interceptor.

Example 6-4. LoggingAround.java
public class LoggingAround implements MethodInterceptor {     private SessionFactory factory;     public SessionFactory getFactory( ) {         return factory;     }     public void setFactory(SessionFactory factory) {         this.factory = factory;     }     private void logEvent(String methodName, String message)             throws Exception {         Session s = null;         LogEvent le = new LogEvent(methodName, new Date( ), message);         try {             s = factory.openSession( );             s.save(le);         } catch (Exception ex) {             //log the exception         } finally {             s.close( );         }     }     public Object invoke(MethodInvocation methodInvocation)            throws Throwable {         logEvent(methodInvocation.getMethod( ).getName( ), "Entering call.");         Object result = methodInvocation.proceed( );         logEvent(methodInvocation.getMethod( ).getName( ), "Leaving call.");         return result;     } }

Example 6-5 shows the new configuration.

Example 6-5. RentABike-servlet.xml
<bean  >    <property name="factory"><ref local="sessionFactory"/></property> </bean> <bean  >    <property name="advice">       <ref local="loggingAround"/>    </property>    <property name="patterns">       <list>          <value>.*save.*</value>       </list>    </property> </bean> <bean  >     <property name="storeName"><value>Bruce's Bikes</value></property>     <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <bean       >     <property name="proxyInterfaces">        <value>com.springbook.RentABike</value>     </property>     <property name="interceptorNames">        <list>           <value>transactionInterceptor</value>           <value>saveAdvisor</value>           <value>rentaBikeTarget</value>        </list>     </property> </bean>

The table results in Example 6-6 show the before and after advice being called only for save-related methods.

Example 6-6. Examining the contents of the logging table
+---------+--------------+------------+----------------+ | eventId | methodName   | dateTime   | message        | +---------+--------------+------------+----------------+ |      14 | saveBike     | 2004-10-13 | Entering call. | |      15 | saveBike     | 2004-10-13 | Leaving call.  | |      16 | saveCustomer | 2004-10-13 | Entering call. | |      17 | saveCustomer | 2004-10-13 | Leaving call.  | |      18 | saveBike     | 2004-10-13 | Entering call. | |      19 | saveBike     | 2004-10-13 | Leaving call.  | +---------+--------------+------------+----------------+

The end result is exactly what we expect. Each time one of the specified methods gets called on our target, the advice fires. We've got declarative auditing. In fact, we can code any service and make it declarative.

    team bbl



    Spring. A developer's Notebook
    Spring: A Developers Notebook
    ISBN: 0596009100
    EAN: 2147483647
    Year: 2005
    Pages: 90

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net