Desvendando o Spring Application Context
Tags: java, kotlin, programming, springframework
Published: 2022-02-05 18:55:00


![Spring](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1v4ohxlcfva022dfz3ys.png)

> _Este é um Post bem teórico, mas se você já trabalha ou está interessando em conhecer um pouco sobre **Spring Framework** invista um tempinho para ler este conteúdo porque é extremamente importante._

O **Spring Framework** fornece um modelo abrangente de programação e configuração para aplicativos corporativos modernos baseados em **Java** em qualquer tipo de plataforma de implantação.
Um elemento chave do **Spring** é o suporte de infra-estrutura no nível do aplicativo: o **Spring** se concentra no “encanamento” dos aplicativos corporativos, para que as equipes possam se concentrar na lógica de negócios no nível do aplicativo, sem vínculos desnecessários a ambientes de implantação específicos.

![Disclamer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vftyo3r58dq7vlibgai3.png) 

## Um pouco de História

Para quem está chegando no universo **Java Web** agora e já chega aprendendo **Spring Boot** não tem ideia de como era burocrático construir aplicações Web em **Java** antes.
Quando usávamos **Java EE** e queríamos delegar responsabilidades para um contexto mais global do seu código tínhamos que fazer isso usando um Servidor de Aplicação, se queríamos por exemplo usar um pool de conexão ou uma mensageria, tínhamos que usar os tais Servidores de Aplicação por exemplo: JBoss(Red Hat), WebSphere(IBM), WebLogic(Oracle) e isso tornava tanto o desenvolvimento quanto o processo de implantação bem burocrático.
Lógico que dependendo do Domínio que você estivesse desenvolvendo um Servidor de Aplicação era necessário, mas quando estava desenvolvendo uma aplicação simples isso era muito ruim, desde o setup de desenvolvimento até a implantação. Isso gerava uma curva de aprendizado bem grande quando as vezes queríamos apenas construir uma aplicação simples e implantar em um servidor simples também.
Na época já tínhamos o _Tomcat_ que era bem simples de trabalhar, mas não era um _Servidor de Aplicação_ e sim um WebServer e não implementava as tais features de um Servidor de Aplicação.
Ai nessa época veio o **Spring Framework** com essa proposta de subir um Contexto(**Application Context**) onde ele gerenciava objetos para sua aplicação, assim você poderia delegar tais responsabilidades para o Framework e se concentrar mais em suas Regras de Negócio, então conseguimos por exemplo usar as _Injeções de Dependências_ do **Spring** e deixar a responsabilidade de gerenciar o ciclo de vida de Objetos em memoria para o Spring.
E agora conseguíamos usando o **Spring Framework** desfrutar de recursos de um Servidor de Aplicação usando apenas nosso querido Apache Tomcat. **\o/**

![Spring Projects](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2mlphfjtppaq5deh6c1r.png)
 

## O tal de Aplication Context

Todo aplicativo **Spring** requer um _Contexto_, um local onde todos os componentes são registrados. Poderíamos pensar nisso como um diretório central de instâncias de objetos criados e armazenados. Quando usamos o **Spring Framework** e criamos algo, por exemplo, um conjunto de conexões, ele é registrado em nosso contexto ou quando criamos nossos próprios componentes(_Beans_, veja meu artigo **[Desvendando os Beans](https://dev.to/fabianogoes/desvendando-os-beans-do-spring-usando-kotlin-26c1)** do _Spring_ usando Kotlin) eles também serão registrados neste Contexto. Portanto, se em outra parte do aplicativo precisamos de um desses componentes, em vez de criá-lo novamente, podemos usa-lo dentro da instancia do Contexto(**IoC**).

Toda essa troca de responsabilidade funciona basicamente com as Annotations, usamos uma _Annotation_ para dizer que o **Spring** deve se Auto Configurar(`@EnableAutoConfiguration`), uma outra Annotation para dizer onde o **Spring** deve procurar por possíveis Componentes(`@ComponentScan`), outras Annotations para dizer que o Spring deve se responsabilizar pela gerencia de estado deste Componente(`@Component`, `@Service`, `@Repository`, `@Controller`), e por fim quando queremos usar algum Componente desses que estão no tal Contexto usamos a Annotation `@Autowired` e com ela dizemos para o Spring que ele deve procurar em seu Contexto algum Componente equivalente ao que precisamos e Injetar na variável onde estamos usando essa Annotation, e essa foi uma das primeiras features que justificava o uso do **Spring Framework** que é: **Spring IoC** que está dentro do pacote _Core_ Technologies do **Spring**.

![Team](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zld2075eqtsm4i3fk163.png)

## Mas e a Configuração disso tudo ?
Bom, aqui tocamos em um ponto de muita discussão desde sempre no mundo Java, Os tais XML de configuração. Nessa época, mesmo com o surgimento do tão amado Spring Framework ainda existia muitas XMLs de configuração, o que ainda deixava tudo muito burocrático.
Tínhamos um servlet-context.xml onde precisávamos configurar um bocado de coisas e perdíamos muito tempo com isso.
Se tiver curiosidade, segue um exemplo bem resumido de um xml desse:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<annotation-driven />
	<resources mapping="/resources/**" location="/resources/" />
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	<context:component-scan base-package="com.eprogramar.springjpa com.eprogramar.springjpa.dao" />
	<beans:bean	class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"></beans:bean>
	<beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<beans:property name="dataSource" ref="dsSpringJPA" />
		<beans:property name="jpaVendorAdapter">
			<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
		</beans:property>
	</beans:bean>
	<beans:bean id="dsSpringJPA" class="org.apache.commons.dbcp.BasicDataSource">
		<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<beans:property name="url" value="jdbc:mysql://localhost:3306/test" />
		<beans:property name="username" value="root" />
		<beans:property name="password" value="123" />
	</beans:bean>
  	<tx:annotation-driven />
	<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
	</beans:bean>
</beans:beans>
```
 
Então tínhamos que configurar **XML** para o **Contexto do Spring**, _XML_ para configuração de _JPA/Hibernate_, e isso era de fato muito burocrático, até a chegada do **Spring Boot**(Deus abençoe o **Spring Boot**) ai sim as coisas começaram a ficar produtivas e divertidas no desenvolvimento Java principalmente para a Aplicações Web.

> **Spring Boot** merece um artigo dedicado a ele e vou tentar fazer isso em breve, por hora quero apenas trazer minha humilde opinião sobre quem viveu essa evolução e pode desfrutar dos ganhos de verdade. Isso é bem diferente de quem chega hoje e pega a coisa toda pronta.

Dito isso, quero finalizar ilustrando a configuração necessário hoje com o **Spring Boot**, esse é um exemplo utilizando Spring em uma aplicação _Kotlin_.

![Spring Application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bptehbd5vrftb11s294.png)
 
Se olharmos essa Annotation `@SpringBootApplication` por dentro veremos que ela tem outras Annotations bem interessantes por exemplo a `@ComponentScan` que é responsável por dizer para o Spring, onde ele deve procurar por Classes que devem ser gerenciadas como um Bean e devem ser registradas no **Application Context**.

![Spring Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64yi93c7rwdm0sjytafc.png)
 

> Uma vez que temos o **Entrypoint** de nossa aplicação anotada com @SpringBootApplication, o Spring usará como ponto de partida para fazer o **Scan**, e todas os pacotes desse nível para dentro serão escaneados em busca de possíveis Beans, e você pode usar a Annotation @ComponentScan para customizar e ensinar o Spring à procurar por Beans em outros pacotes, por exemplo em libs que você possa estar usando dentro de sua empresa.

## Conclusão

O **Spring Application Context** é uma peça fundamental dentro do ecossistema do _Framework_ e é muito importante o desenvolvedor entender como ele funciona uma vez que decide usar esse fantástico framework que o **Spring**.
Esse foi um artigo bem teórico mas muito necessário, espero que gostem e que seja útil no seu desenvolvimento como Programador.
um forte abraço e até a próxima.

## Referências

- https://spring.io/projects/spring-framework#overview
- https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
- https://medium.com/@fabiano_goes/desvendando-os-beans-do-spring-usando-kotlin-59dc55934caa