sexta-feira, 30 de dezembro de 2011

Configurando o framework em aplicações WEB

Até agora para configurar o framework, através de seu módulo principal, o CORE, seja
programaticamente, via XML, ou qualquer outra implementação seja em nosso código seja a partir de um método main, seja a partir de uma classe que recebe essa responsabilidade ou qualquer outra estrutura temos que chamar sempre CoreContext.getInstance().initialize(coreConfiguration); ou coreConfiguration.initializeContext(); para configurar e inicializar o framework.

Em uma aplicação WEB é comum que um framework forneça recursos para que a configuração seja feita de forma automática, sem precisar de nada programaticamente.
Este recurso também é provido pelo lindbergframework através de um ServletContextListener e da definição de alguns no Deployment Descriptor (web.xml) da aplicação. A partir daí quando o servidor for inicializado e a aplicação publicada o lindbergframework será automaticamente configurado baseado nas configurações passadas.

Essa configuração é muito simples. Baseia-se em declarar no web.xml da aplicação o ServletContextListener provido pelo lindbergframework e definir os parâmetros (<context-param>) informando onde está o arquivo de configuração do framework e qual a implementação do parser de configuração a ser usado, se será Xml, Properties, Txt, seja lá qual for, sendo que para este último é esperado uma implementação de WebCoreConfiguration.

Tanto o local onde se encontra o arquivo de configuração quando a implementação de WebCoreConfiguration a ser usada não são requeridos pois ambos possuem valores padrão. O path do arquivo de configuração caso não seja definido tem como padrão o valor lindberg-config.xml na raiz do classpath do projeto. E a implementação de WebCoreConfiguration, caso não seja declarada, é usada como padrão:

org.lindbergframework.web.core.configuration.WebClassPathXmlCoreConfiguration.

Abaixo é descrito um exemplo do que precisaria ser adicionado ao nosso web.xml se fossemos usar o mesmo arquivo de configuração que usamos nos exemplos anteriores só que agora em um projeto WEB para configurar o framework de forma automática:

<context-param><!--(ISTO É OPCIONAL. O caminho padrão para o arquivo de configuração é 'lindbergconfig.xml' localizado na raiz do classpath)-->
    <param-name>lindbergConfigLocation</param-name>
    <param-value>org/lindbergframework/configuracao/lindberg-config.xml</param-value>
</context-param>
<context-param> <!--(ISTO É OPCIONAL)-->
    <param-name>lindbergConfigClass</param-name>
    <param-alue>org.lindbergframework.core.context.WebClassPathXmlCoreConfiguration</param-value>
</context-param>
<listener>
    <listener-class>org.lindbergframework.web.LindbergContextLoaderListener</listener-class>
</listener>


No exemplo acima observe que adicionamos o listener LindbergContextLoaderListerner, que é o ServletContextListener provido pelo lindbergframework e que sabe como configurar de forma automatizada o framework. Adicionamos o parâmetro lindbergConfigLocation que é onde está o arquivo de configuração.

Esta propriedade é opcional e caso não seja declarada, o framework usa o nome e local padrão para o arquivo de configuração, que é 'lindberg-config.xml' na raiz do classpath. Importante dizer que o arquivo não obrigatoriamente tem que ser um XML, isto depende da implementação de WebCoreConfiguration que estiver usando. Se, por exemplo, ocorresse a necessidade de usar uma implementação para configurações definidas em um arquivo .properties então este parâmetro apontaria para um arquivo properties, da mesma forma se eu criar minha própria implementação de WebCoreConfiguration que trabalha com um arquivo TXT segundo uma formatação que eu criei então esse parâmetro vai apontar para um arquivo TXT que segue o padrão de formatação definido. Para que haja essa flexibilidade, é que é possível definir a implementação de WebCoreConfiguration que deve ser usada através do parâmetro lindbergConfigClass.

Passos para configuração no web.xml:
• Declarar o listener: org.lindbergframework.web.LindbergContextLoaderListener
• Declarar os Parâmetros via :
-- ◦ lindbergConfigLocation: Local onde está o arquivo de configuração caso o -- arquivo de configuração não siga o padrão é 'lindberg-config.xml' na raiz do
-- classpath.

-- ◦ lindbergConfigClass: Implementação de CoreConfiguration que efetuará o parser -- da configuração. Quando não definido este parâmetro a implementação padrão,
-- WebClassPathXmlCoreConfiguration, é usada.

A partir daí é só iniciar o servidor que o a configuração será efetuada automaticamente e você verá no console as mensagens de log informando o processo de inicialização do contexto WEB do framework.

ATENÇÃO: Para alguns servidores é necessário adicionar a lib do xmlbeans direto nas libs do servidor de modo a sobrescrever a lib padrão provida pelo mesmo. Isso se faz necessário quando ao subir o servidor se obtenha uma mensagem de erro como a descrita abaixo indicando conflito de carregamento de classes do xmlbeans.

”...Loader constraint violation in interface itable initialization: when resolving method
"org.apache.xmlbeans.impl.store.Xobj$NodeXobj.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHa
ndler;)Ljava/lang/Object;" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the
current class, org/apache/xmlbeans/impl/store/Xobj$NodeXobj, and the class loader (instance of ) for
interface org/w3c/dom/Node have different Class objects for the type org/w3c/dom/UserDataHandler used in the
signature”

A Classe CoreContext

A classe CoreContrext é um singleton e provê acesso a toda configuração do módulo CORE do framework. Para obter a instância singleton do contexto de configuração de core basta chamar

CoreContext.getInstane()

As configurações definidas para o core como o pacote base para o contexto de
injeção de dependências, a implementação da BeanFactory, módulos dependêntes, e qualquer outra configuração de CORE pode ser acessada via CoreContext.

Veja a documentação da classe CoreContext aqui.

Inicializando CoreContext usando configuração XML

Para este post é necessário que você leia antes este outro post: LINK

Abaixo é mostrado o mesmo processo de configuração do CORE demonstrado no post citado acima, só que usando o XML.

<config-property name="exemplo" value="com.aplicacao.Exemplo">
       <property value="valor da propriedade1" constructor-arg="true" />
       <property constructor-arg="true">
            <list>
                exemplo list string 1;
                exemplo list string 2;
                exemplo list string 3;
                exemplo list string N;
            </list>
       </property>
       <property name="propriedade3">
            <array>
                exemplo list string 1;
                exemplo list string 2;
                exemplo list string 3;
                exemplo list string N;
            </array>
       </property>
</config-property>

Para este exemplo vamos considerar que o XML acima esteja no pacote org.lindbergframework.configuracao e que o nome do XML é o padrão, lindberg-config.xml, seguindo o mesmo nome do schema.


XmlCoreConfiguration coreConfiguration = new ClassPathXmlCoreConfiguration("org/lindbergframework/configuracao/lindberg-config.xml");
coreConfiguration.initializeContext();


Observe que agora inicializamos o contexto de forma diferente do exemplo anterior.

Os dois exemplos, tanto o deste post quanto o do post citado resultarão na seguinte saída no console informando o status da inicialização da configuração do framework:

INFO: Initializing Lindberg Core Context
INFO: Lindberg Core Context initialized

Neste exemplo observe que foi utilizada a classe ClassPathXmlCoreConfiguration para criar a configuração. Essa classe é uma extensão natural de XmlCoreConfiguration para trabalhar com um arquivo de configuração que está dentro do classpath do projeto. Os dois exemplos mostrados ao final configuram o framework respectivamente a partir de:


- CoreContext.getInstance().initialize(coreConfiguration);
- coreConfiguration.initializeContext();

A partir daí o core do framework está configurado e podemos por exemplo obter uma instância de um bean a partir da fábrica. Supondo que no pacote org.lindbergframework.exemplo.beans tenha um bean cujo ID seja “pessoaDAO” então podemos obter uma instância desse bean chamando a BeanFactory como demonstrado a seguir, isso só pode ser feito após claro a devida configuração do CORE.

IPessoaDAO pessoaDAO = CoreContext.getInstance().getBeanFactory().getBean("pessoaDAO");

Uma outra forma de fazer a mesma coisa e obter o mesmo bean seria:

IPessoaDAO pessoaDAO = UserBeanContext.getInstance().getBean("pessoaDAO");

Todo o funcionamento do mecanismo de injeção de dependência será detalhado mais a frente. Aqui foi demonstrado apenas como exemplo do uso da configuração na prática.

– Uso do carácter '#' no XML para definir propriedades e métodos getters estáticos

Imagine que você quer por algum motivo que o framework chame um método 'get' seu para obter a instância da implementação de BeanFactory a ser usada, imagine que você queira isso pois por algum motivo você precise fazer algum processamento nesse método 'get' para efetuar alguma customização, registro de log, enfim. Ou imagine ainda que por algum motivo você quer que a String com pacote base (onde o framework encontrará os beans que farão parte do contexto de 'inversão de controle' de modo que a criação, injeção de dependência desses seja responsabilidade do framework) esteja em numa constante em uma de suas classes de modo que você possa usá-la em outros lugares no seu projeto centralizando esse atributo na forma de uma constante.

Para estes casos o framework provê o recurso de usar o carácter coringa '#'. O uso desse carácter antes da definição de um valor de uma propriedade no arquivo XML de configuração informa que o valor real daquela propriedade será obtido através da chamada ao método 'get' estático e público ou da constante também estática e pública definidos na String ao qual o carácter '#' é fixado.

Isso só é possível para propriedades e métodos que são estáticos e públicos e nos casos do método que seja um método seguindo o padrão de nomenclatura de métodos getter, não sendo para este último caso necessário preceder o nome do método no XML com 'get' pois o framework já busca o método adequado baseado no padrão de nomenclatura.

Por exemplo, se quiséssemos que as duas propriedades mostradas anteriormente para o CORE fossem obtidas agora da seguinte forma:

- di-basepackage: A partir de uma constante estática e pública chamada BASEPACKAGE na classe com.soft.MyConstants;

- BeanFactory: A partir de um método getter público e estático chamado getMyBeanFactory na classe com.soft.MyFactoryConfiguration.

Então a nova configuração seria:

<core>
       <config-property name="lindberg.core.di-basepackage"
               value="#com.soft.MyConstants.BASEPACKAGE"/>
       <config-property name="lindberg.core.beanfactory"                value="#com.soft.MyFactoryConfiguration.myBeanFactory"/>
</core>

Observe que agora os valores das propriedades estão precedidos do carácter '#'. Observe que o valor da propriedade beanFactory, que aponta para um método 'get', não contém o prefixo 'get' ou seja o nome completo do método 'getMyBeanFactory' e sim apenas 'myBeanFactory'. Isso pode ser feito pois o framework por padrão vai buscar o método 'get', seguindo os padões de nomenclatura, fazendo 'get' + 'MyBeanFactory' e invoca o método 'getMyBeanFactory'. Da mesma forma caso deseje informar diretamente o nome do método o framework percebe e o invoca da mesma forma. Seguindo este pensamento a definição da propriedade beanFactory poderia ser feita sem nenhuma mudança no processamento da seguinte forma:

<config-property name="lindberg.core.beanfactory"value="#com.soft.MyFactoryConfiguration.getMyBeanFactory"/>

Agora informamos diretamente o nome completo do método getMyBeanFactory. O framework vai detectar que isso foi feito e não fará nenhuma conversão de nomenclatura, invocando diretamente o método informando.

NOTA: Apenas métodos e propriedades públicos e estáticos podem ser usados com '#'.

Configuração do CORE do lindbergframework

Como foi dito no post sobre a arquitetura, que pode ser visto nesse Link , o framework é composto de módulos. Neste post vamos abordar como configurar o módulo core, suas flexibilidades, alternativas e pontos de extensão.

O módulo CORE na atual versão é responsável por prover toda a estrutura de contextos no que diz respeito a beans como inversão de controle para provimento de injeção de depêndencia e é ele quem define toda a arquitetura e contratos que os outros módulos devem seguir.

Na versão atual, 1.0, o framework só prover a configuração do pacote base para scaneamento de beans candidatos a injeção de dependência e que farão parte do contexto de beans de usuário e que podem ser obtidos a partir do singleton UserBeanContext.

- Configurando o CORE

A configuração do módulo CORE é composta por informações como pacote base para resolver beans para injeção de dependência, fábrica de beans, módulos dependêntes que se deseja utilizar. As configurações de CORE são mais simples, pois dizem respeito apenas as configurações gerais que são definidas para o núcleo do framework.

As duas propriedades que podem ser configuradas no CORE são:

- lindberg.core.di-basepackage (propriedade requerida):
Pacote base de beans para injeção.
Constante que define essa propriedade: CoreConfiguration.CONFIG_PROPERTY_DI_BASEPACKAGE;

- lindberg.core.beanfactory (se não for definida a fábrica padrão será usada - AnnotationBeanFactory):
Fábrica de beans a ser usada.
Constante que define essa propriedade: CoreConfiguration.CONFIG_PROPERTY_BEAN_FACTORY

Vamos definir uma configuração de CORE para os seguintes valores usando as duas implementações de CoreConfiguration na prática:

- Pacote base de beans para injeção (lindberg.core.di-basepackage) = org.lindbergframework.exemplo.*

- Bean factory (lindberg.core.beanfactory) = org.lindbergframework.beans.di.context.AnnotationBeanFactory


Estas duas propriedades são suficientes para configurarmos o core para usarmos apenas o mecanismo de injeção de dependência. Neste caso os beans para injeção serão procurados dentro do pacote org.lindbergframework.exemplo e o ponto asterisco “.*” define que o framework também procurará beans para injeção de dependência dentro dos sub-pacotes de org.lindbergframework.exemplo e sub-pacotes destes e assim em diante.

O lindbergframework define uma interface chamada BeanFactory que define uma fábrica de beans que pode ser usada para obtenção de instâncias de beans dentro do contexto de injeção de dependência corrente. Neste caso foi definida a implementação de uma fábrica de beans que trabalha em conjunto com annotations. Mais a frente serão abordados os detalhes dessa interface BeanFactory e de todo o mecanismo de injeção de dependência.

– Configurando o CORE na Prática - Programaticamente
Abaixo é mostrado um exemplo da implementação e uso dessas configurações programaticamente direto com código java usando a implementação SimpleCoreConfiguration:

SimpleCoreConfiguration coreConfiguration = new SimpleCoreConfiguration();
coreConfiguration.setDiBasePackage("org.lindbergframework.exemplo.*");
coreConfiguration.setBeanFactory(new AnnotationBeanFactory());
CoreContext.getInstance().initialize(coreConfiguration);


OBSERVAÇÃO: O trecho de código
CoreContext.getInstance().initialize(...)
poderia ser substituido por
coreConfiguration.initializeContext();
- Esse método em CoreConfiguration faz com que o contexto de CORE
com esta configuração seja inicializado.


O trecho acima cria uma instância de SimpleCoreConfiguration, seta as propriedades pacote base onde encontrar os beans que poderão ser usados dentro do contexto de DI (dependecy injection ou injeção de dependência) e a instância da fábrica de beans a ser usada pelo mecanismo de DI. Definidas as propriedades de configuração então o último passo é configurar o módulo core baseado nestas configurações. Para fazer isso é obtida a instância singleton de CoreContext via CoreContext.getInstance() e o método initialize passando a configuração criada é invocado. Pronto, o módulo CORE já está pronto para ser usado e em qualquer lugar você pode invocar CoreContext.getInstance().getBeanFactory() para obter a instância configurada da fábrica definida e chamar o método getBean da fábrica para obter uma
instância de um bean desejado passando o “ID“ deste. Um outro modo de se obter uma instância de um bean através da mesma fábrica é usar a classe UserBeanContext via
UserBeanContext.getInstance().getBean(id). O mecanismo de injeção de dependência será detalhado mais a frente, aqui está apenas sendo demonstrado os conceitos de configuração.

– Configurando o CORE na prática – Usando XML

A seguir é demonstrado a mesma configuração só que usando uma implementação de CoreConfiguration para configuração baseada em XML. O schema que define as configurações baseadas em XML é detalhado a seguir.

Schema: http://www.lindbergframework.org/schema/lindberg-config.xsd

O schema no que diz respeito a tag <core> para definições de configurações de CORE é ilustrado de forma detalhada na imagem abaixo:



Abaixo é mostrado um simples arquivo de configuração de core que define as mesmas configurações do exemplo anterior.

<?xml version="1.0" encoding="UTF-8"?>
<lindberg-configuration
          xmlns="http://www.lindbergframework.org/schema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.lindbergframework.org/schema/lindberg-config.xsd">

<core>
       <config-property name="lindberg.core.di-basepackage"
              value="org.lindbergframework.exemplo.*"/>
       <config-property name="lindberg.core.beanfactory"
             value="org.lindbergframework.beans.di.context.AnnotationBeanFactory"/>
</core>

</lindberg-configuration>

NOTA: A beanfactory está sendo definida mas lembre que esta propriedade não é requerida e quando não informada a factory padrão, AnnotationBeanFactory, é usada automaticamente pelo framework.

– A tag <config-property>

A tag <config-property> é a mais importante de todo o documento XML de configuração. Ela é
usada para a definição de propriedades de configuração. Estas propriedades definem todo o comportamento dos componentes fornecidos pelo framework como o pacote base para buscar beans de injeção automática, gerenciador de transações, resolvedor de comandos sql, schema de banco padrão que deve ser usado, entre outros. Estes últimos são abordados mais a frente, quando o componente de persistência (LINP) for apresentado.

Esta é uma tag basicamente de nome e valor, onde o atributo nome define a chave da propriedade de configuração e o atributo valor define o valor que será usado na configuração para esta propriedade.

Esta tag fornece a flexibilidade de definição de propriedades que serão setadas na objeto valor desta propriedade no momento da inicialização e propriedades que serão usadas como parâmetro para um construtor específico.

Supondo que nós tivéssemos uma propriedade de configuração de CORE cujo a chave é exemplo e o valor para esta chave fosse a classe com.aplicacao.Exemplo e esta classe tivesse uma propriedade String chamada propriedade1, então a definição dessa propriedade seria:

* Definindo a inicialização simples de propriedades dentro de uma propriedade de configuração


<config-property name="exemplo" value="com.aplicacao.Exemplo">
          <property name="propriedade1" value="valor da propriedade1" />
</config-property>


Observe que foi usada uma nova tag dentro da tag <config-property>. Ela serve para definir
propriedades de inicialização e parâmetros de construtor de propriedades de configuração.

A tag <property> pode ser usada um número ilimitado de vezes dentro da tag <config-property> de acordo com a necessidade. Neste caso a utilizamos uma única vez, para definir o set da String 'valor da propriedade1' na propriedade de nome propriedade1 na instância do objeto do tipo com.aplicacao.Exemplo para a chave de configuração Exemplo. A propriedade propriedade1 será setada no momento da criação do objeto com.aplicacao.Exemplo. Se tivéssemos uma propriedade2, bastaria declarar uma outra tag <property> dentro de <config-property> da mesma forma que a propriedade1.

* Definindo a inicialização de propriedades do tipo List ou Array dentro de uma propriedade de configuração

Suponha agora que tivéssemos então as propriedade2 e propriedade3 e estas fossem respectivamente uma List e um Array e ambas de String. Esta tag fornece a flexibilidade de inicialização de listas e arrays de Strings diretamente pelo XML de configuração. Abaixo é mostrado como ficaria a tag <config-property> com a inicialização destas duas propriedades.

<config-property name="exemplo" value="com.aplicacao.Exemplo">
       <property name="propriedade1" value="valor da propriedade1" />
       <property name="propriedade2">
            <list>
                exemplo list string 1;
                exemplo list string 2;
                exemplo list string 3;
                exemplo list string N;
            </list>
       </property>
       <property name="propriedade3">
            <array>
                exemplo array string 1;
                exemplo array string 2;
                exemplo array string 3;
                exemplo array string N;
            </array>
       </property>
</config-property>

No trecho acima agora definimos duas novas propriedades propriedade2 e propriedade3. A primeira é uma List e a segunda um Array. Observe que agora temos duas novas tags para serem usadas dentro da tag <property>, as tags <list> e <array>. A primeira define uma lista e a segunda um array, ambos de Strings. Os valores de cada uma dessas tags são definidos com o conteúdo entre a tag de abertura e fechamento onde cada elemento da List ou Array é separado por um carácter ';'. Dentro da tag <property> se tem a flexibilidade de usar qualquer um dos dois tipos sendo que nunca os dois ao mesmo tempo dentro da mesma <property>.

* Inicialização de propriedades de configuração usando um construtor específico

Agora suponhamos que a nossa classe Exemplo tenha um construtor que recebe uma String e uma
coleção de Strings e queiramos usar este construtor para a criação do objeto Exemplo transformando a nossa definição da propriedade1 e propriedade2 em parâmetros para o construtor. Suponha também que ainda assim queiramos setar a propriedade propriedade3 da mesma forma que o exemplo anterior.

A nossa nova definição da tag <config-property> ficaria da seguinte forma:

<config-property name="exemplo" value="com.aplicacao.Exemplo">
       <property value="valor da propriedade1" constructor-arg="true" />
       <property constructor-arg="true">
            <list>
                exemplo list string 1;
                exemplo list string 2;
                exemplo list string 3;
                exemplo list string N;
            </list>
       </property>
       <property name="propriedade3">
            <array>
                exemplo list string 1;
                exemplo list string 2;
                exemplo list string 3;
                exemplo list string N;
            </array>
       </property>
</config-property>

Observe que o que mudou neste exemplo foi que a tag que definiam as propriedades propriedade1 e propriedade2 agora não tem mais definidos seus atributos nome, pois agora são parâmetros de construtor e agora ao invés disto estas tags tem a propriedade constructor-arg definido para 'true', indicando que estes serão atributos de construtor. Então o construtor que o framework buscaria para criar a instancia de Exemplo seria:

public Exemplo(String,List<String>)

Após a chamada a este construtor e a criação da instancia, a propriedade propriedade3 seria setada com o Array de String definido chamando o método setPropriedade3.

VEJA TAMBÉM COMO CONFIGURAR O CORE USANDO XML NO POST: LINK

Contextos - A interface ComponentContext

A interface ComponentContext define um contexto de módulo dentro do lindbergframework e duas implementações são definidas: contexto de Core e contexto de Persistência. As implementações de cada um desses contextos são respectivamente CoreContext e LinpContext. Definidos através de um singleton para todo sistema sendo necessário a chamada ao método getInstance definido em cada um deles para a obtenção da instância corrente.

Um contexto só pode ser usado se este estiver ativo. Para ativar um contexto o método initialize deve ser invocado passando como parâmetro a instancia da configuração sobre o qual o contexto se baseará.

A interface ComponentContext também define outros métodos auxiliares, como isActive para a checagem do status do contexto quanto a ativo e inativo, finalize para efetuar o encerramento do contexto e verifyContext para verificação da usabilidade do contexto. Qualquer tentativa de uso de um contexto sem usabilidade resultará em uma IllegalStateContextException.

Não é necessário se aprofundar no estudo dos contextos pois o framework faz todo o trabalho e interage com os contextos quando necessário e não é necessário se preocupar com nada referente a isso, pelo menos para o uso comum. Mas caso precise de alguma customização ou adotar o mecanismo de contextos do framework para criar seu próprio contexto para usar onde quer que seja, o framework lhe fornece esse recurso.

A Arquitetura por trás do módulo configuration

O lindbergframework como qualquer outro framework é configurável e customizável de acordo com as necessidades de cada projeto. A interface Configuration define o contrato de classes que configuram o framework. Existem ainda duas interfaces que estendem desta ultima. Uma para configurações do core, CoreConfiguration e outra para configurações específicas do componente de persistencia, LinpConfiguration.

São fornecidas junto com a distribuição padrão do framework implementações para configurar o framework usando XML e programaticamente via código java direto. Abaixo são descritas as implementações padrão destas interfaces que não precisam ser conhecidas para usar o framework o próprio framework instancia e usa a implementação padrão de cada uma delas se uma implementação específica não for definida.

- ClassPathXmlCoreConfiguration: Implementação de CoreConfiguration para definição da configuração do módulo CORE via XML definido no classpath da aplicação, baseado no schema:
http://www.lindbergframework.org/schema/lindberg-config.xsd

- SimpleCoreConfiguration: Implementação de CoreConfiguration para definição da configuração do módulo CORE programaticamente.

- SimpleLinpConfiguration: Implementação de LinpConfiguration para definição da configuração do módulo de persistência (LINP) programaticamente.

- XmlLinpConfiguration: Implementação de LinpConfiguration para definição da configuração do módulo de persistência (LINP) via XML baseado no schema:
http://www.lindbergframework.org/schema/linp-sqlMapping.xsd

* Processo de Configuração

O processo de configuração é iniciado e gerenciado a partir do módulo CORE. O módulo core é configurado e este configura os outros módulos dependentes, caso algum esteja sendo usado, como por exemplo o módulo LINP.

A interface CoreConfiguration define um método chamado getModules que devolve as
configurações dos módulos dependentes de modo que no momento da inicialização da configuração do CORE dentro de seu contexto os contextos dependentes que estão sendo usados são automaticamente configurados e inicializados. Este método devolve as implementações de Configuration que devem ser inicializadas. Cada implementação desta pode ser configuração via XML, programaticamente, usando arquivos .properties, arquivos .txt, enfim qualquer implementação que se desejar. Normalmente não haverá
necessidade de se escrever implementações de Configuration pois o framework já fornece implementações padrão que devem ser utilizadas. Mas se for necessário estender qualquer uma dessas de modo a mudar seu comportamento padrão ou mesmo fornecer uma implementação especifica, sinta-se a vontade mas saiba o que está fazendo.

Arquitetura do lindbergframework

O framework é composto em módulos divididos em responsabilidades. Cada módulo contribui no gerenciamento e configuração dos recursos providos. A figura a seguir ilustra a arquitetura atual do lindbergframework na versão 1.x.




– Módulos e responsabilidades

• Beans: Responsável por todo gerenciamento de inversão de controle (IOC) e injeção de dependências que o framework provê. O LDIC (Lindberg Dependency Injection Container) é o mecanismo responsável por resolver as instancias de beans solicitados, bem como suas respectivas dependências, e injeta-los no lugar certo na hora certa de acordo com a necessidade de cada bean.

• Integration: Módulo responsável pela integração e operacionalidade entre o lindberg e outros frameworks. Na versão 1.x o framework fornece integração com Spring, Adobe Flex e JSF.

• Context: Responsável por toda configuração, beans e gerenciamento em nível de escopo de cada camada: core, persistence, web, etc...

• Configuration: Toda a parte de configuração do framework por escopo é responsabilidade deste módulo. Os escopos de configuração estão organizados em Core, Persistence e Web onde o web tem um escopo interno específico para configurações de core que inicializará as configurações nos outros
escopos.