Beans, entendendo a base fundamental do Spring Framework
- #Spring Framework
- #Java
Beans, entendendo a base fundamental do Spring Framework
Bean é um conceito-chave do Spring Framework. Portanto, entender essa noção é crucial para entender o framework e usá-lo de maneira eficaz.
Beans são instancias de classes que são gerenciadas por um Spring Ioc container.
Na definição oficial: Um bean é um objeto que é instanciado, montado e gerenciado por um Spring IoC container. Essa definição é concisa e vai direto ao ponto, mas não detalha um elemento importante: porque utilizar os beans? Vamos dar uma olhada mais de perto para ver o que são e os benefícios que utilizar beans nos trazem.
Para entender a importância do uso de beans é fundamental você ter o conhecimento de dois padrões de projetos muito utilizados no universo da programação: a inversão de controle e a injeção de dependencia.
O conceito de inversão de Controle
A inversão de controle é um padrão de projeto que prega remover de uma classe a responsabilidade de instanciar outras classes e passar essa responsabilidade para um componente externo do sistema, seja ele um framework, um container, um serviço, uma outra classe e etc. Existem várias formas de se fazer inversão de controle, as principais são:
Programação orientada a eventos críticos
Injeção de Dependência
Linguagens de Programação Funcional
Nesse artigo focaremos na inversão por injeção de dependência pois essa é a tecnologia utilizada pelo Spring.
O que é a injeção de dependencia
A injeção de dependência é um padrão de projetos que visa “injetar” as dependências usadas por uma classe em vez de deixar com essa classe a responsabilidade de instanciá-las (entenda por dependência como os atributos e métodos de outros objetos utilizados por essa classe), nessa definição podemos notar a correlação com a inversão de controle, pois ambas retiram das classes a responsabilidade de instanciar seus objetos dependentes. Como dito antes a injeção de dependência é uma forma de se realizar a inversão de controle.
Um exemplo
Suponha que temos uma declaração de classe:
public class ProdutoDAO {
private MySql mysql;
public String RegistrarProduto(Produto produto) {
// faz outros cálculos de preço
return this.mysql.Salvar(produto);
}
public ProdutoDAO(MySql m) {
this.mysql = m;
}
}
Essa classe possuí uma dependência da classe MySql
public class MySql {
public String Salvar(Produto produto) {
//código com lógica para a persistência de dados
return "Produto salvo";
}
}
Normalmente, criamos objetos com os construtores de suas classes:
MySql m = new MySql();
ProdutoDAO p = new ProdutoDAO(m);
Não há nada de errado com essa abordagem, mas não seria bom gerenciar as dependências de uma maneira melhor?
Imagine uma aplicação com dezenas ou até centenas de classes. Às vezes queremos compartilhar uma única instância de uma classe em todo o aplicativo, outras vezes precisamos de um objeto separado para cada caso de uso e assim por diante.
Gerenciar tantos objetos é nada menos que um pesadelo. É aqui que o Spring com seu Ioc container vem para nos socorrer.
Em vez de construir dependências por si só, um objeto pode recuperar suas dependências de um contêiner IoC. Tudo o que precisamos fazer é fornecer ao contêiner os metadados de configuração apropriados, e o melhor é que esses metadados podem ser fornecidos por meio de tags (anotações) em nosso código.
Como dito anteriormente, os objetos gerenciados pelo Spring Ioc são chamados de beans, ao adicionarmos a anotação @Component
à definição de uma classes, estamos criando um bean para aquela classe.
Outras anotações também podem ser usadas para criar beans, como por exemplo @Controller
, @Service
, @Repository
, etc.
Criando beans usando anotações
Primeiramente, vamos decorar as classes ProdutoDAO e MySql com a anotação @Componen e em seguida vamos adicionar logs aos seus construtores para monitorarmos sempre que esses objetos forem criados:
@Component
public class ProdutoDAO {
private MySql mysql;
public String RegistrarProduto(Produto produto) {
// faz outros cálculos de preço
return this.mysql.Salvar(produto);
}
public ProdutoDAO(MySql m) {
System.out.println("Criando objeto ProductDAO");
this.mysql = m;
}
}
@Component
public class MySql {
public String Salvar(Produto produto) {
return "Produto salvo";
}
public MySql(){
System.out.println("Criando objeto Mysql");
}
}
Precisamos declarar as classes MySql e ProdutoDAO como beans pois a ideia principal é injetar beans dentro de outros beans.
Ao executarmos uma aplicação com essas duas classes, veremos as seguintes mensagens em meio aos logs em nosso terminal:
Isso acontece porque o Spring IoC se encarrega de instanciar a classe ProdutoDAO automaticamente, juntamente com todas as suas dependências , no nosso caso, o objeto MySql.
Tipos e nomes dos Beans
No Spring, os beans possuem um nome de identificação e um tipo, esse tipo é referente a sua classe.
Os nomes dos beans são utilizados para a sua identificação, portanto, não pode haver dois beans com o mesmo nome.
O tipo do bean é utilizado pelo Ioc para identificar em que parte do código ele será aplicado, mais especificadamente, o tipo do bean é utilizado para determinar em quais variáveis (objetos) ele será referenciado. Como uma variável não pode referenciar dois valores ao mesmo tempo, se existirem dois beans do mesmo tipo, um deles deve ser anotado com @Primary indicando que esse bean é o default para ser referenciado nos objetos.
Para saber mais sobre os beans e o funcionamento do Spring Framework acesse sua documentação oficial. Até a próxima.