[[gemfire-bootstrap]]
= Bootstrapping a Spring ApplicationContext in Pivotal GemFire

== Introduction

Normally, a _Spring_-based application will <<bootstrap,bootstrap Pivotal GemFire>> using _Spring Data for Pivotal GemFire's.
Just by specifying a `<gfe:cache/>` element using the _Spring Data for Pivotal GemFire_ XML namespace, a single, embedded Pivotal GemFire
peer `Cache` instance is created and initialized with default settings in the same JVM process as your application.

However, it is sometimes necessary, perhaps a requirement imposed by your IT organization, that Pivotal GemFire be fully managed
and operated using the provided Pivotal GemFire tool suite, such as with
http://geode.apache.org/docs/guide/11/tools_modules/gfsh/chapter_overview.html[Gfsh].  By using _Gfsh_,
Pivotal GemFire will bootstrap your _Spring_ application context rather than the other way around.  Instead of
an application server, or a Java main class using _Spring Boot_, whatever, Pivotal GemFire does the bootstrapping and will
host your application.

Keep in mind, however, that Pivotal GemFire is not an application server.  In addition, there are limitations to using
this approach where Pivotal GemFire cache configuration is concerned.

[[gemfire-bootstrap-gfsh]]
== Using Pivotal GemFire to Bootstrap a Spring Context Started with Gfsh

In order to bootstrap a _Spring_ application context in Pivotal GemFire when starting a Pivotal GemFire Server process using _Gfsh_,
a user must make use of Pivotal GemFire's
http://geode.apache.org/docs/guide/11/basic_config/the_cache/setting_cache_initializer.html[Initalizer] functionality.
An Initializer block can declare a callback application that is launched after the cache is initialized by Pivotal GemFire.

An Initializer is declared within an
http://geode.apache.org/docs/guide/11/reference/topics/cache_xml.html#initializer[initializer] element
using a minimal snippet of Pivotal GemFire's native `cache.xml`.  The `cache.xml` file is required in order to bootstrap
the _Spring_ application context, much like a minimal snippet of _Spring_ XML config is needed to bootstrap
a _Spring_ application context configured with component scanning (e.g. `<context:component-scan base-packages="..."/>`)

Fortunately, such an Initializer is already conveniently provided by the framework, the
http://docs.spring.io/spring-data-gemfire/docs/current/api/org/springframework/data/gemfire/support/SpringContextBootstrappingInitializer.html[SpringContextBootstrappingInitializer].
A typical, yet very minimal configuration for this class inside Pivotal GemFires's `cache.xml` file will look like this:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">

  <initializer>
    <class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
    <parameter name="contextConfigLocations">
      <string>classpath:application-context.xml</string>
    </parameter>
  </initializer>

</cache>
----

The `SpringContextBootstrappingInitializer` class follows similar conventions as _Spring's_ `ContextLoaderListener`
class used to bootstrap a _Spring_ application context inside a Web Application, where application context
configuration files are specified with the `contextConfigLocations` Servlet Context Parameter.

In addition, the `SpringContextBootstrappingInitializer` class can also be used with a `basePackages` parameter
to specify a comma-separated list of base packages containing appropriately annotated application components
that the _Spring_ container will search in order to find and create _Spring_ beans and other application components
on the classpath:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">

  <initializer>
    <class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
    <parameter name="basePackages">
      <string>org.mycompany.myapp.services,org.mycompany.myapp.dao,...</string>
    </parameter>
  </initializer>

</cache>
----

Then, with a properly configured and constructed `CLASSPATH` along with `cache.xml` file shown above, specified as
a command-line option when starting a Pivotal GemFire Server in _Gfsh_, the command-line would be:

[source]
----
gfsh>start server --name=Server1 --log-level=config ...
    --classpath="/path/to/application/classes.jar:/path/to/spring-data-geode-<major>.<minor>.<maint>.RELEASE.jar"
    --cache-xml-file="/path/to/geode/cache.xml"
----

The `application-context.xml` can be any valid _Spring_ context configuration meta-data including all the SDG namespace
elements.  The only limitation with this approach is that a Pivotal GemFire cache cannot be configured using
the _Spring Data for Pivotal GemFire_ namespace.  In other words, none of the `<gfe:cache/>` element attributes,
such as `cache-xml-location`, `properties-ref`, `critical-heap-percentage`, `pdx-serializer-ref`, `lock-lease`, etc,
can be specified.  If used, these attributes will be ignored.

The reason for this is that Pivotal GemFire itself has already created an initialized the cache before the Initializer
gets invoked.  As such, the cache will already exist and since it is a "Singleton", it cannot be re-initialized
or have any of it's configuration augmented.

[[gemfire-bootstrap-lazywiring]]
== Lazy-Wiring Pivotal GemFire Components

_Spring Data for Pivotal GemFire_ already provides existing support for wiring Pivotal GemFire components, such as `CacheListeners`,
`CacheLoaders`, `CacheWriters` and so on, that are declared and created by Pivotal GemFire in `cache.xml` using
SDG's `WiringDeclarableSupport` class as described in <<apis:declarable:autowiring>>.  However, this only works
when _Spring_ is the one doing the bootstrapping (i.e. bootstrapping Pivotal GemFire).

When your _Spring_ application context is bootstrapped by Pivotal GemFire, then these Pivotal GemFire application components go unnoticed
since the _Spring_ application context does not even exist yet!  The _Spring_ application context will not get created
until Pivotal GemFire calls the Initializer block, which only occurs after all the other Pivotal GemFire components and configuration
have already been created and initialized.

So, in order to solve this problem, a new `LazyWiringDeclarableSupport` class was introduced that is, in a sense,
_Spring_ application context aware.  The intention of this abstract base class is that any implementing class
will register itself to be configured by the _Spring_ container that will eventually be created by Pivotal GemFire
once the Initializer is called.  In essence, this give your Pivotal GemFire defined application components a chance
to be configured and auto-wired with _Spring_ beans defined in the _Spring_ application context.

In order for your Pivotal GemFire application components to be auto-wired by the _Spring_ container, create an application class
that extends the `LazyWiringDeclarableSupport` and annotate any class member that needs to be provided as
a _Spring_ bean dependency, similar to:

[source,java]
----
public class UserDataSourceCacheLoader extends LazyWiringDeclarableSupport
    implements CacheLoader<String, User> {

  @Autowired
  private DataSource userDataSource;

  ...
}
----

As implied in the `CacheLoader` example above, you might necessarily (although, rarely) have defined both
a Region and `CacheListener` component in Pivotal GemFire `cache.xml`.  The `CacheLoader` may need access to an application DAO,
or perhaps a _Spring_ application context defined JDBC `DataSource` for loading `Users` into a Pivotal GemFire `REPLICATE` Region
on start.

CAUTION: Be careful when mixing the different life-cycles of Pivotal GemFire and the _Spring_ Container together
in this manner as not all use cases and scenarios are supported. The Pivotal GemFire `cache.xml` configuration would be
similar to the following (which comes from SDG's test suite):

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">

  <region name="Users" refid="REPLICATE">
    <region-attributes initial-capacity="101" load-factor="0.85">
      <key-constraint>java.lang.String</key-constraint>
      <value-constraint>org.springframework.data.gemfire.repository.sample.User</value-constraint>
      <cache-loader>
        <class-name>
          org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTest$UserDataStoreCacheLoader
        </class-name>
      </cache-loader>
    </region-attributes>
  </region>

  <initializer>
    <class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
    <parameter name="basePackages">
      <string>org.springframework.data.gemfire.support.sample</string>
    </parameter>
  </initializer>

</cache>
----
