Visão Geral dos Conceitos Fundamentais do Contêiner IoC do Spring

Contêiner IoC do Spring

BeanFactory

public interface BeanFactory {
    String PREFIX_FABRICA_BEAN = "&";
}

Normalmente, chamar getObject() retorna o bean em si. Utilizar o prefixo & permite obter a fábrica (FactoryBean) que produz esse bean.

Ciclo de Vida do Bean

A sequência padrão e completa do ciclo de vida de um bean no Spring, conforme definido na documentação dos implementadores do BeanFactory, é a seguinte:

As implementações do BeanFactory devem suportar as interfaces padrão de ciclo de vida. O conjunto completo de métodos de inicialização e sua ordem padrão é:

  1. Injeção de Dependências (Autowiring)
  2. Configuração de propriedades (BeanNameAware, BeanFactoryAware, etc.)
  3. Processadores (BeanPostProcessor) antes da inicialização
  4. Inicialização via InitializingBean
  5. Método de inicialização customizado
  6. Processadores (BeanPostProcessor) após a inicialização
  7. Destruição via DestructionAwareBeanPostProcessor
  8. Destruição via DisposableBean
  9. Método de destruição customizado

As interfaces Aware fornecem acesso a funcionalidades específicas do contêiner:

  • BeanNameAware: Permite obter o nome do bean no contêiner.
  • BeanFactoryAware: Fornece acesso à fábrica de beans atual, possibilitando chamar serviços do contêiner.
  • ApplicationContextAware: Concede acesso ao ApplicationContext corrente, também permitindo utilizar serviços do contêiner.
  • MessageSourceAware: Permite obter a fonte de mensagens, facilitando o acesso a textos.
  • ApplicationEventPublisherAware: Oferece um publicador de eventos da aplicação.
  • ResourceLoaderAware: Fornece um carregador de recursos para ler o conteúdo de arquivos externos.
* <li>Métodos {@code postProcessBeforeInitialization} dos BeanPostProcessors
* </li><li>{@code afterPropertiesSet} do InitializingBean
* </li><li>Definição de um método init customizado
* </li><li>Métodos {@code postProcessAfterInitialization} dos BeanPostProcessors
</li>
* <li>Métodos {@code postProcessBeforeDestruction} dos DestructionAwareBeanPostProcessors
* </li><li>{@code destroy} do DisposableBean
* </li><li>Definição de um método destroy customizado
</li>

FactoryBean

Uma interface que depende do BeanFactory para produzir beans personalizados. As principais explicações são:

  • As invocações de getObjectType() e getObject() podem ocorrer no início do processo de bootstrap, antes mesmo da configuração dos pós-processadores.
  • Um bean que implementa esta interface não pode ser tratado como um bean normal.
  • Um FactoryBean é definido como um bean.

Environment

Representa o ambiente de execução da aplicação e é acessado através da interface ConfigurableEnvironment. Suas características incluem:

  • Define dois conceitos principais: profiles e propertise.
  • Acessa propriedades usando a interface PropertyResolver.
  • Os perfis podem ser definidos via XML ou com a anotação @Profile.
  • As fontes de propriedades são diversas: variáveis de sistema da JVM, ambiente do sistema, JNDI, parâmetros do servlet, objetos Properties ad-hoc, Maps, etc.
  • Para resolver placeholders (ex: ${...}) em arquivos XML, utiliza-se PropertySourcesPlaceholderConfigurer.
  • A partir do Spring 3.1, o registro padrão é gerenciado por <context:property-placeholder/>.

ApplicationContext (O Integrador Principal)

extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver

Uma interface que representa uma abstração de capacidade. As interfaces filhas herdam e integram as funcionalidades das interfaces pai. Um ApplicationContext oferece:

  1. Métodos de fábrica de beans para acessar componentes da aplicação (herdados de ListableBeanFactory).
  2. Habilidade genérica para carregar recursos de arquivo (herdada de ResourceLoader).
  3. Capacidade de publicar eventos para ouvintes registrados (herdada de ApplicationEventPublisher).
  4. Capacidade de resolver mensagens, suportando internacionalização (herdada de MessageSource).

Em um contexto web, pode existir um contexto pai para toda a aplicação e contextos filhos independentes para cada servlet.

EnvironmentCapable

Expõe o método Environment getEnvironment(). A interface ConfigurableApplicationContext estende ApplicationContext e Closeable, e sobrescreve o método getEnvironment de EnvironmentCapable, retornando um ConfigurableEnvironment. Isso ocorre porque o Environment básico é somente leitura, enquanto ConfigurableEnvironment permite a personalização.

ApplicationEventPublisher

@FunctionalInterface
public interface ApplicationEventPublisher {

Esta anotação marca interfaces funcionais (com um único método abstrato), facilitando a verificação pelo compilador. Ela considera métodos estáticos, padrões e aqueles herdados de java.lang.Object (como toString) como não abstratos.

ConfigurableListableBeanFactory

Esta interface consolida as capacidades de múltiplas outras:

  • AutowireCapableBeanFactory: Expõe capacidades de injeção de dependências. Outros frameworks podem usá-la para conectar e preencher instâncias de beans. O ApplicationContext a obtém via getAutowireCapableBeanFactory().
  • ListableBeanFactory: Estende BeanFactory para listar todos os beans, em vez de buscar por nome.
  • HierarchicalBeanFactory: Define uma hierarquia de fábricas com métodos como getParentBeanFactory() e containsLocalBean(String name).

ConfigurableListableBeanFactory integra todas essas interfaces adicionando sua própria capacidade de configuração.

ResourcePatternResolver

Uma interface de estratégia para reslover padrões de localização de recursos. Exemplos de prefixos:

  • classpath*:: Pesquisa em todos os jars.
  • classpath:: Pesquisa no classpath atual.

Lifecycle e SmartLifecycle

Pode ser implementado tanto por componentes quanto por contêineres. Sua finalidade é propagar sinais de início/parada para todos os componentes e aplicá-los ao contêiner. Pode ser invocado diretamente ou gerenciado via JMX.

SmartLifecycle oferece uma integração mais sofisticada com as fases de inicialização e desligamento do contexto da aplicação.

ConfigurableApplicationContext

ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

Esta interface estende ApplicationContext adicionando funcionalidades de configuração.

AbstractApplicationContext

abstract class AbstractApplicationContext extends DefaultResourceLoader
      implements ConfigurableApplicationContext {

Uma classe abstrata que implementa o padrão de projeto Template Method, onde subclasses concretas fornecem as implementações dos métodos abstratos. Ela detecta beans especiais definidos em sua fábrica interna, registrando automaticamente BeanFactoryPostProcessors, BeanPostProcessors e ApplicationListeners.

Também implementa o carregamento de recursos estendendo DefaultResourceLoader.

O método central para atualizar o contexto da aplicação é refresh():

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      prepareRefresh();
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      prepareBeanFactory(beanFactory);
      try {
         postProcessBeanFactory(beanFactory);
         invokeBeanFactoryPostProcessors(beanFactory);
         registerBeanPostProcessors(beanFactory);
         initMessageSource();
         initApplicationEventMulticaster();
         onRefresh();
         registerListeners();
         finishBeanFactoryInitialization(beanFactory);
         finishRefresh();
      }
      catch (BeansException ex) {
         destroyBeans();
         cancelRefresh(ex);
         throw ex;
      }
      finally {
         resetCommonCaches();
      }
   }
}

Tags: Spring IoC BeanFactory ApplicationContext Inversão de Controle

Publicado em 7-8 18:55