Dashboard > Terracotta Developer Documentation > Home > Architecture > Terracotta for Spring Architecture
  Terracotta Developer Documentation Log In   View a printable version of the current page.  
  Terracotta for Spring Architecture
Added by Eugene Kuleshov, last edited by Nathaniel Harward on Nov 28, 2006  (view change)
Labels: 
(None)

Terracotta for Spring Architecture

Overview

Terracotta for Spring is a transparent clustering runtime for the Spring Framework. The core features of this runtime include clustering of Spring-managed components (singleton and scope-bound), as well as events, published to the Spring's ApplicationContext. Combining those features together with other components of the Spring Framework make it possible to implement more advanced features, such as clustering of Quartz jobs, exposing clustered data to Ajax clients with DWR, managing your entire cluster from a single access point with Spring JMX layer and much more.

Terracotta for Spring is built on top of the DSO product. On one hand it is using DSO features to apply clustering aspects to components managed by Spring framework. On the other hand it is taking advantage of Spring's component model and simplifying the configuration needed for clustering those components. Spring-managed components are named in the Spring configuration and their life cycle is owned by Spring framework (for singleton and scope beans). We can select which components need to be clustered, leaving all the others local. If we map those named components into the distributed object graph managed by DSO they become clustered.

From an implementation point of view, Terracotta for Spring is using DSO instrumentation, the DSO internal API as well as the AspectWerkz AOP engine. That allows us to plug into the Spring core and add clustering features transparently.

AspectWerkz allowed to declare join points in Spring code and implement additional functionality in plain Java. This still have good runtime performance at the load time because of the tight integration of the AspectWerkz with DSO bytecode pipeline. Aspects specific to Spring integration are declared in SpringAspectModule which is triggered on loading of the Spring classes.

Clustering Spring beans

Like with raw DSO, it is necessary to establish object identity for any clustered object instance. Since objects are managed by Spring Framework and more specifically, by Spring's bean factory (actually BeanFactory or ApplicationContext), we need to be able to identify each bean factory instance that can be created in user's application. Each of those bean factories represents a logical context, which can be exposed as a Root in DSO. Unfortunately Spring does not provide anything out of the box that can be used as unique identity for those contexts. To work around this limitation we match bean factory instances based on class loader name (or web application name) and collection of the configuration files used to initialize BeanFactory. Note that class loader name (established by DSO) is optional. This allows to handle most common scenarios when application either has single ApplicationContext or several bean factories are initialized from different configurations. It also allows us to generate synthetic name for DSO Root or assign an alias that can be shared between several bean factories and explicitly represent same DSO Root.

The next step is to establish a mapping between classes that DSO needs to know about and Spring bean names. This is done by the BeanDefinitionProtocol aspect that is watching all the BeanDefinitions created when parsing Spring configuration (the convention is that all aspects ends with *Protocol). The collected information is used to register includes for DSO instrumentation at runtime. It also gives a starting point for automatic discovery of the implicit classes that need to be included for DSO instrumentation using quick static analysis of bean's class fields and super classes. This way we only need to specify bean names that need to be clustered and most (if not all) of the required classes will be discovered automatically.

The actual clustering for these beans is done by the GetBeanProtocol, which is intercepting the BeanFactory.getBean() call and makes sure that the returned instance is clustered. The implementation is checking if corresponding DSO Root already has an instance with the requested name (or scope) and if it doesn't then delegates the creation to the Spring Framework and then adds it to the DSO Root. Otherwise, if instance already have been created on other node, then on the first request it is delegating to Spring to create a shadow bean instance used to initialize non-clustered state of distributed bean and then return distributed instance - which then contains partly cluster and partly local state.

Clustering ApplicationContext Events

Similarly, for events that can be published in Spring's ApplicationContext can be specified in the configuration using their class names. Then the ApplicationContextEventProtocol aspect is applied to the ApplicationContext.publishEvent() method and the interceptEvent() advice is using DSO's distributed method invocation (DMI) to send events to other nodes. In order for this to work the instance on which the method is invoked should be clustered by DSO. So its identity is known and remote nodes can fetch the instance by its identity. In order to make that happened, the registerContext() advice is registering the aspect instance in the DSO Root for the current Spring's bean factory.

Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators