Archive

Posts Tagged ‘Spring Python’

Spring Python i merge’owanie kontekstów

October 12th, 2009 No comments

Miłym ficzerem Spring Pythona jest merge’owanie kontekstów utworzonych w różnych składniach, czyli możliwe jest utworzenie części kontekstów korzystając ze składni Pythona, części w XML-u, a części, powiędzmy, w YAML-u (co jest nowością w Spring Pythonie 1.1).

Możemy więc mieć np. taką strukturę plików:

.
|-- ctx-merging.py
|-- standard_ctx.py
`-- dynamic-ctx.xml
  • ctx-merging.py – kod źródłowy naszej aplikacji,
  • standard_ctx.py – stały kontekst naszej aplikacji, zapisany w składni Pythona,
  • dynamic-ctx.xml – kontekst XML-owy zmieniający się w trakcie działania aplikacji, np. trzymane są tutaj różne ustawienia aplikacji, które userzy mogą zmieniać.

Poniżej jest kod źródłowy plików, nieważne, że konteksty niczego mądrego w tych przykładach nie przechowują, chodzi tylko o zilustrowanie zasady:


ctx-merging.py

# -*- coding: utf-8 -*-

# Spring Python
from springpython.context import ApplicationContext
from springpython.config import XMLConfig

# Nasz własny, stały, kontekst aplikacyjny.
from standard_ctx import StandardApplicationContext

# Kontekst w Pythonie.
standard_ctx = StandardApplicationContext()

# Kontekst w XML-u, dynamicznie update'owany przez aplikację.
dynamic_ctx = XMLConfig("./dynamic-ctx.xml")

# Zmerge'owane konteksty, zarówno ten w Pythonie jak i XML-owy.
container = ApplicationContext([standard_ctx, dynamic_ctx])

# Pobranie obiektów z kontenera IoC.
factory = container.get_object("factory")
my_int = container.get_object("my_int")

# Wyświetlenie obiektów.
print factory
print my_int


standard_ctx.py

# -*- coding: utf-8 -*-

from springpython.config import PythonConfig
from springpython.config import Object
from springpython.context import scope

class StandardApplicationContext(PythonConfig):
    def __init__(self):
        super(StandardApplicationContext, self).__init__()

    @Object(scope.PROTOTYPE)
    def my_int(self):
        return 11


dynamic-ctx.xml

<?xml version="1.0" encoding="UTF-8"?>
<objects xmlns="http://www.springframework.org/springpython/schema/objects"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/springpython/schema/objects
           http://springpython.webfactional.com/schema/context/spring-python-context-1.0.xsd">

 <object id="factory"
       class="springpython.database.factory.Sqlite3ConnectionFactory"
          scope="prototype">
 </object>

</objects>

Cały trick polega na tym, że w standard_ctx.py możemy w wygodnej, czytelnej dla nas, postaci kodu źródłowego Pythona trzymać część kontekstu, która nie zmienia się. Lepiej trzymać to w postaci Pythona, bo przecież jest to postać najczytelniejsza, po co męczyć się i edytować XML? W dynamic-ctx.xml trzymamy z kolei to, co może zmieniać się i do czego raczej nie będziemy sami zaglądali, żeby edytować. Lepiej jest więc to trzymać w XML-u, bo dzięki temu mamy łatwą serializację.

Co, jeśli więcej niż jeden kontekst trzymają dwa tak samo obiekty? Np. w obydwu kontekstach byłby obiekt ‘factory’? Wynik jest wtedy niezdefiniowany. Oczywiście zawsze można zajrzeć do źródeł i mieć jasność :-) ale i tak będzie oznaczało to poleganie na nieudokumentowanej funkcjonalności.

Jeszcze raz zwracam uwagę na YamlConfig – od wersji 1.1 Spring Pythona dostępna będzie bajecznie czytelna postać, która bije konfigurację XML-ową bez mrugnięcia okiem.

Share
Categories: Software Tags: ,