Einrichtung der Anwendung und der allgemeinen Dienste

Einleitung

Wie bereits in der Einführung erwähnt, ist ein Anwendungskontext eine XML-Datei mit folgendem Rahmen:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 ...
<beans>
Durch den Platzhalter-Mechanismus können Teile des Anwendungskontextes im Framework abgelegt werden, ohne an Flexibilität einzubüßen. Es gibt einmal data-access-context.xml, in dem die Klassen rund um den Datenbankzugriff definiert sind. Dann gibt es noch den security-context.xml, wobei dieser mehr eine leere Hülle ist. Die Einschränkung der Berechtigung ist bereits an vielen Stellen im Framework vorgesehen, allerdings gab es für mich noch keinen echten Bedarf, sodass hier noch Lücken bestehen.

Funktionsweise

Während des Starts der Anwendung werden alle definierten Klassen aus dem Anwendungskontext erzeugt. Damit sind sie zwar vorhanden, aber noch nicht für die Anwendung verfügbar. Vergleichbar mit privaten Variablen einer Klasse. Nur die Anwendungsstarthelfer haben Zugriff direkten Zugriff auf den Anwendungskontext.

Definition einer Instanz

Im Anwendungskontext werden Instanzen definitiert, die beim Start der Anwendung erstellt werden. Die einfachste Form einer solchen Definition ist:

<bean id="sysInfo" class="de.schwarzrot.system.SysInfo" />
das heißt, jede Definition einer Instanz fängt mit dem Tag <bean an. Die Parameter, die unbedingt angegeben werden müssen, sind "id" und "class".

Manche Klassen haben keinen Default-Konstruktor, d.h. sie erfordern Parameter. Diese können wie folgt angegeben werden:

<bean id="dataSourceManager" class="de.schwarzrot.data.access.jdbc.DataSourceManager">
    <constructor-arg>
        <ref bean="dsConfig" />
    </constructor-arg>
</bean>
Bei diesem Beispiel wird auch deutlich, wie man eine bereits existierende Instanz verwenden kann. Dafür gibt es den Tag <ref

Instanz-Variablen belegen

Wenn eine Instanz erzeugt wurde, kann es notwendig sein, ihr noch einige Instanz-Variablen mit anderen Werten zu belegen. Dazu gibt es das tag <property

<bean id="prefsEntityManager" class="de.schwarzrot.data.access.pref.PreferencesEntityManager">
    <property name="entityUtils"
               ref="entityUtils" />
    <property name="entityIntrospector>
        <ref="preferencesEntityIntrospector" />
    </property>
    <property name="applicationName"
             value="${de/schwarzrot/app/config/SystemDefault/applicationName}" />
    <property name="schemaName"
             value="${de/schwarzrot/app/config/SystemDefault/dsSchema}" />
</bean>
Hier kommt auch nochmal der Platzhalter zum Einsatz. Ferner zeigen die beiden ersten Property-Tags die unterschiedliche Verwendung von Referenzen. Gleiches kann bei den Werten auch verwendet werden.

Property vom Typ Liste

Natürlich kann eine Instanz-Variable auch mit einer Liste belegt werden:

<bean id="converterFactory" class="de.schwarzrot.data.support.ConverterFactory">
    <property name="converters">
        <list>
            <ref bean="cnvDate" />
            <ref bean="cnvBoolean" />
            <ref bean="cnvInt" />
            <ref bean="cnvLong" />
            <ref bean="cnvByte" />
            <ref bean="cnvShort" />
            <ref bean="cnvFloat" />
            <ref bean="cnvDouble" />
            <ref bean="cnvColor" />
            <ref bean="cnvEnum" />
            <ref bean="cnvFile" />
            <ref bean="cnvString" />
            <ref bean="cnvEntity" />
        </list>
    </property>
</bean>

Property vom Typ Map

... gleiches gilt für Maps:

<bean id="appServices" class="de.schwarzrot.app.support.ApplicationServiceConfigurer">
    <property name="services">
        <!--
       // IMPORTANT: don't change the keys,
       // change the bean definition above (if ever)
       -->
        <map>
            <entry key="de.schwarzrot.data.transaction.support.TransactionFactory">
                <ref bean="transactionFactory" />
            </entry>
            <entry key="de.schwarzrot.ui.image.ImageFactory" value-ref="imageFactory" />
            <entry key="de.schwarzrot.ui.Desktop" value-ref="desktop" />
            <entry key="de.schwarzrot.data.support.ConverterFactory"
             value-ref="converterFactory" />
        </map>
    </property>
</bean>
Da bei einer Map sowohl ein Schlüssel, als auch ein Wert per Referenz verwendet werden kann, gibt es für die inline-Schreibweise die Tags "value-ref" und "key-ref".

Instanzen veröffentlichen

Im letzten Absatz wurde bereits die Klasse eingeführt, die für die Veröffentlichung zuständig ist: ApplicationServiceConfigurer.

Alle Instanzen, die in die Map der "services" Property eingetragen sind, werden beim Start der Anwendung im ApplicationServiceProvider registriert. Deshalb ist der Schlüssel der absolute Klassenname der Klasse oder des Interfaces, unter welchem die Instanz gefunden werden soll.

Aus diesem Grund ist es auch unerläßlich, dass die Schlüssel nicht geändert werden. Natürlich kann eine Instanz unter mehreren unterschiedlichen Schlüsseln veröffentlicht werden.