Primavera - Guia Rápido

Spring é a estrutura de desenvolvimento de aplicativos mais popular para Java empresarial. Milhões de desenvolvedores em todo o mundo usam o Spring Framework para criar código de alto desempenho, facilmente testável e reutilizável.

O Spring framework é uma plataforma Java de código aberto. Ele foi inicialmente escrito por Rod Johnson e foi lançado pela primeira vez sob a licença Apache 2.0 em junho de 2003.

A mola é leve quando se trata de tamanho e transparência. A versão básica do framework Spring tem cerca de 2 MB.

Os principais recursos do Spring Framework podem ser usados ​​no desenvolvimento de qualquer aplicativo Java, mas existem extensões para a construção de aplicativos da web na plataforma Java EE. O Spring framework visa tornar o desenvolvimento J2EE mais fácil de usar e promove boas práticas de programação ao habilitar um modelo de programação baseado em POJO.

Benefícios de usar o Spring Framework

A seguir está uma lista de alguns dos grandes benefícios do uso do Spring Framework -

  • O Spring permite que os desenvolvedores desenvolvam aplicativos de classe corporativa usando POJOs. O benefício de usar apenas POJOs é que você não precisa de um produto de contêiner EJB, como um servidor de aplicativos, mas tem a opção de usar apenas um contêiner de servlet robusto, como Tomcat ou algum produto comercial.

  • A primavera é organizada de forma modular. Mesmo que o número de pacotes e classes seja substancial, você precisa se preocupar apenas com aqueles de que precisa e ignorar o resto.

  • O Spring não reinventa a roda, em vez disso, ele realmente faz uso de algumas das tecnologias existentes, como vários frameworks ORM, frameworks de registro, timers JEE, Quartz e JDK e outras tecnologias de visualização.

  • Testar um aplicativo escrito com Spring é simples porque o código dependente do ambiente é movido para esta estrutura. Além disso, usando POJOs JavaBeanstyle, fica mais fácil usar injeção de dependência para injetar dados de teste.

  • A estrutura da web do Spring é uma estrutura MVC da web bem projetada, que fornece uma ótima alternativa para estruturas da web, como Struts ou outras estruturas da web com engenharia excessiva ou menos populares.

  • O Spring fornece uma API conveniente para converter exceções específicas de tecnologia (lançadas por JDBC, Hibernate ou JDO, por exemplo) em exceções consistentes e não verificadas.

  • Os contêineres IoC leves tendem a ser leves, especialmente quando comparados aos contêineres EJB, por exemplo. Isso é benéfico para desenvolver e implantar aplicativos em computadores com memória e recursos de CPU limitados.

  • O Spring fornece uma interface de gerenciamento de transações consistente que pode ser reduzida para uma transação local (usando um único banco de dados, por exemplo) e expandida para transações globais (usando JTA, por exemplo).

Injeção de Dependência (DI)

A tecnologia com a qual o Spring é mais identificado é o Dependency Injection (DI)sabor de Inversão de Controle. oInversion of Control (IoC)é um conceito geral e pode ser expresso de muitas maneiras diferentes. A injeção de dependência é apenas um exemplo concreto de inversão de controle.

Ao escrever um aplicativo Java complexo, as classes do aplicativo devem ser o mais independentes possível de outras classes Java para aumentar a possibilidade de reutilizar essas classes e testá-las independentemente de outras classes durante o teste de unidade. A injeção de dependência ajuda a colar essas classes e, ao mesmo tempo, mantê-las independentes.

O que é injeção de dependência exatamente? Vamos examinar essas duas palavras separadamente. Aqui, a parte da dependência se traduz em uma associação entre duas classes. Por exemplo, a classe A é dependente da classe B. Agora, vamos examinar a segunda parte, injeção. Tudo isso significa que a classe B será injetada na classe A pelo IoC.

A injeção de dependência pode acontecer na forma de passar parâmetros para o construtor ou por pós-construção usando métodos setter. Como a injeção de dependência é o coração do Spring Framework, explicaremos esse conceito em um capítulo separado com um exemplo relevante.

Programação Orientada a Aspectos (AOP)

Um dos principais componentes do Spring é o Aspect Oriented Programming (AOP)estrutura. As funções que abrangem vários pontos de um aplicativo são chamadascross-cutting concernse essas questões transversais são conceitualmente separadas da lógica de negócios do aplicativo. Existem vários bons exemplos comuns de aspectos, incluindo registro, transações declarativas, segurança, armazenamento em cache, etc.

A principal unidade de modularidade em OOP é a classe, enquanto em AOP a unidade de modularidade é o aspecto. DI ajuda a desacoplar seus objetos de aplicação uns dos outros, enquanto AOP ajuda a desacoplar interesses transversais dos objetos que eles afetam.

O módulo AOP do Spring Framework fornece uma implementação de programação orientada a aspectos, permitindo que você defina interceptores de método e pontos de corte para desacoplar claramente o código que implementa a funcionalidade que deve ser separada. Discutiremos mais sobre os conceitos de Spring AOP em um capítulo separado.

O Spring pode ser potencialmente um balcão único para todos os seus aplicativos empresariais. No entanto, o Spring é modular, permitindo que você escolha quais módulos são aplicáveis ​​a você, sem ter que trazer o resto. A seção a seguir fornece detalhes sobre todos os módulos disponíveis no Spring Framework.

O Spring Framework fornece cerca de 20 módulos que podem ser usados ​​com base em um requisito de aplicativo.

Core Container

O Core Container consiste nos módulos Core, Beans, Context e Expression Language, cujos detalhes são os seguintes -

  • o Core O módulo fornece as partes fundamentais da estrutura, incluindo os recursos IoC e Injeção de Dependência.

  • o Bean módulo fornece BeanFactory, que é uma implementação sofisticada do padrão de fábrica.

  • o Contextmódulo é construído sobre a base sólida fornecida pelos módulos Core e Beans e é um meio para acessar quaisquer objetos definidos e configurados. A interface ApplicationContext é o ponto focal do módulo Context.

  • o SpEL O módulo fornece uma linguagem de expressão poderosa para consultar e manipular um gráfico de objeto em tempo de execução.

Acesso / integração de dados

A camada de Acesso / Integração de Dados consiste nos módulos JDBC, ORM, OXM, JMS e Transação, cujos detalhes são os seguintes -

  • o JDBC O módulo fornece uma camada de abstração JDBC que elimina a necessidade de codificação tediosa relacionada ao JDBC.

  • o ORM O módulo fornece camadas de integração para APIs populares de mapeamento objeto-relacional, incluindo JPA, JDO, Hibernate e iBatis.

  • o OXM O módulo fornece uma camada de abstração que suporta implementações de mapeamento Object / XML para JAXB, Castor, XMLBeans, JiBX e XStream.

  • O serviço de mensagens Java JMS módulo contém recursos para produzir e consumir mensagens.

  • o Transaction O módulo oferece suporte ao gerenciamento de transações programáticas e declarativas para classes que implementam interfaces especiais e para todos os seus POJOs.

Rede

A camada da Web consiste nos módulos Web, Web-MVC, Web-Socket e Web-Portlet, cujos detalhes são os seguintes -

  • o Web O módulo fornece recursos básicos de integração orientados para a web, como funcionalidade de upload de arquivo multipartes e a inicialização do contêiner IoC usando ouvintes de servlet e um contexto de aplicativo orientado para web.

  • o Web-MVC módulo contém a implementação Model-View-Controller (MVC) do Spring para aplicativos da web.

  • o Web-Socket O módulo fornece suporte para comunicação bidirecional baseada em WebSocket entre o cliente e o servidor em aplicativos da web.

  • o Web-Portlet O módulo fornece a implementação MVC a ser usada em um ambiente de portlet e espelha a funcionalidade do módulo Web-Servlet.

Diversos

Existem alguns outros módulos importantes como AOP, Aspects, Instrumentation, Web e módulos de teste, cujos detalhes são os seguintes -

  • o AOP O módulo fornece uma implementação de programação orientada a aspectos, permitindo que você defina interceptores de método e pontos de corte para desacoplar claramente o código que implementa a funcionalidade que deve ser separada.

  • o Aspects O módulo fornece integração com AspectJ, que é novamente uma estrutura AOP poderosa e madura.

  • o Instrumentation O módulo fornece suporte de instrumentação de classe e implementações de carregador de classe para serem usados ​​em determinados servidores de aplicativos.

  • o MessagingO módulo fornece suporte para STOMP como o subprotocolo WebSocket a ser usado em aplicativos. Ele também suporta um modelo de programação de anotação para rotear e processar mensagens STOMP de clientes WebSocket.

  • o Test O módulo suporta o teste de componentes Spring com estruturas JUnit ou TestNG.

Este capítulo irá guiá-lo sobre como preparar um ambiente de desenvolvimento para iniciar seu trabalho com Spring Framework. Também ensinará como configurar JDK, Tomcat e Eclipse em sua máquina antes de configurar o Spring Framework -

Etapa 1 - Configure o Java Development Kit (JDK)

Você pode baixar a versão mais recente do SDK no site Java da Oracle - Java SE Downloads. Você encontrará instruções para instalar o JDK nos arquivos baixados, siga as instruções fornecidas para instalar e configurar a configuração. Por fim, defina as variáveis ​​de ambiente PATH e JAVA_HOME para se referir ao diretório que contém java e javac, normalmente java_install_dir / bin e java_install_dir respectivamente.

Se você estiver executando o Windows e tiver instalado o JDK em C: \ jdk1.6.0_15, deverá inserir a seguinte linha em seu arquivo C: \ autoexec.bat.

set PATH=C:\jdk1.6.0_15\bin;%PATH% 
set JAVA_HOME=C:\jdk1.6.0_15

Alternativamente, no Windows NT / 2000 / XP, você terá que clicar com o botão direito do mouse em Meu computador, selecionar Propriedades → Avançado → Variáveis ​​de ambiente. Então, você terá que atualizar o valor de PATH e clicar no botão OK.

No Unix (Solaris, Linux, etc.), se o SDK estiver instalado em /usr/local/jdk1.6.0_15 e você usar o shell C, deverá colocar o seguinte em seu arquivo .cshrc.

setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH 
setenv JAVA_HOME /usr/local/jdk1.6.0_15

Alternativamente, se você usar um Ambiente de Desenvolvimento Integrado (IDE) como Borland JBuilder, Eclipse, IntelliJ IDEA ou Sun ONE Studio, você terá que compilar e executar um programa simples para confirmar que o IDE sabe onde você instalou o Java. Caso contrário, você terá que realizar uma configuração adequada conforme fornecido no documento do IDE.

Etapa 2 - Instale a API Apache Common Logging

Você pode baixar a versão mais recente da API Apache Commons Logging em https://commons.apache.org/logging/. Depois de baixar a instalação, descompacte a distribuição binária em um local conveniente. Por exemplo, em C: \ commons-logging-1.1.1 no Windows ou /usr/local/commons-logging-1.1.1 no Linux / Unix. Este diretório terá os seguintes arquivos jar e outros documentos de suporte, etc.

Certifique-se de definir sua variável CLASSPATH neste diretório corretamente, caso contrário, você enfrentará um problema ao executar seu aplicativo.

Etapa 3 - Configurar IDE Eclipse

Todos os exemplos neste tutorial foram escritos usando Eclipse IDE. Portanto, sugerimos que você tenha a versão mais recente do Eclipse instalada em sua máquina.

Para instalar o Eclipse IDE, baixe os binários mais recentes do Eclipse em https://www.eclipse.org/downloads/. Depois de baixar a instalação, descompacte a distribuição binária em um local conveniente. Por exemplo, em C: \ eclipse no Windows ou / usr / local / eclipse no Linux / Unix e, finalmente, defina a variável PATH apropriadamente.

O Eclipse pode ser iniciado executando os seguintes comandos na máquina Windows ou você pode simplesmente clicar duas vezes em eclipse.exe

%C:\eclipse\eclipse.exe

O Eclipse pode ser iniciado executando os seguintes comandos na máquina Unix (Solaris, Linux, etc.) -

$/usr/local/eclipse/eclipse

Após uma inicialização bem-sucedida, se tudo estiver bem, ele deve exibir o seguinte resultado -

Etapa 4 - Configurar Bibliotecas do Spring Framework

Agora, se tudo estiver bem, você pode prosseguir com a configuração de sua estrutura Spring. A seguir estão as etapas simples para baixar e instalar a estrutura em sua máquina.

  • Escolha se deseja instalar o Spring no Windows ou Unix e, em seguida, prossiga para a próxima etapa para baixar o arquivo .zip para Windows e o arquivo .tz para Unix.

  • Baixe a versão mais recente dos binários do framework Spring em https://repo.spring.io/release/org/springframework/spring.

  • No momento de desenvolver este tutorial, spring-framework-4.1.6.RELEASE-dist.zipfoi baixado na máquina Windows. Depois que o arquivo baixado foi descompactado, ele fornece a seguinte estrutura de diretório dentro de E: \ spring.

Você encontrará todas as bibliotecas Spring no diretório E:\spring\libs. Certifique-se de definir sua variável CLASSPATH neste diretório corretamente, caso contrário, você enfrentará um problema ao executar seu aplicativo. Se você estiver usando o Eclipse, não é necessário definir CLASSPATH porque todas as configurações serão feitas por meio do Eclipse.

Depois de concluir esta última etapa, você está pronto para prosseguir com seu primeiro exemplo de Spring no próximo capítulo.

Vamos começar a programação real com Spring Framework. Antes de começar a escrever seu primeiro exemplo usando a estrutura Spring, você deve se certificar de que configurou seu ambiente Spring apropriadamente, conforme explicado no Capítulo Spring - Configuração de Ambiente . Também presumimos que você tenha algum conhecimento prático no Eclipse IDE.

Agora, vamos continuar a escrever um aplicativo Spring simples, que imprimirá "Hello World!" ou qualquer outra mensagem baseada na configuração feita no arquivo de configuração do Spring Beans.

Etapa 1 - Criar projeto Java

A primeira etapa é criar um projeto Java simples usando Eclipse IDE. Siga a opçãoFile → New → Project e finalmente selecione Java Projectassistente da lista de assistentes. Agora nomeie seu projeto comoHelloSpring usando a janela do assistente da seguinte forma -

Depois que seu projeto for criado com sucesso, você terá o seguinte conteúdo em seu Project Explorer -

Etapa 2 - Adicionar bibliotecas necessárias

Como uma segunda etapa, vamos adicionar Spring Framework e bibliotecas comuns de API de registro em nosso projeto. Para fazer isso, clique com o botão direito no nome do seu projetoHelloSpring e depois siga a seguinte opção disponível no menu de contexto - Build Path → Configure Build Path para exibir a janela Java Build Path da seguinte forma -

Agora usa Add External JARs botão disponível sob o Libraries guia para adicionar os seguintes JARs principais dos diretórios de instalação do Spring Framework e Common Logging -

  • commons-logging-1.1.1

  • spring-aop-4.1.6.RELEASE

  • spring-aspects-4.1.6.RELEASE

  • spring-beans-4.1.6.RELEASE

  • spring-context-4.1.6.RELEASE

  • spring-context-support-4.1.6.RELEASE

  • spring-core-4.1.6.RELEASE

  • spring-expression-4.1.6.RELEASE

  • spring-instrument-4.1.6.RELEASE

  • spring-instrument-tomcat-4.1.6.RELEASE

  • spring-jdbc-4.1.6.RELEASE

  • spring-jms-4.1.6.RELEASE

  • spring-messaging-4.1.6.RELEASE

  • spring-orm-4.1.6.RELEASE

  • spring-oxm-4.1.6.RELEASE

  • spring-test-4.1.6.RELEASE

  • spring-tx-4.1.6.RELEASE

  • spring-web-4.1.6.RELEASE

  • spring-webmvc-4.1.6.RELEASE

  • spring-webmvc-portlet-4.1.6.RELEASE

  • spring-websocket-4.1.6.RELEASE

Etapa 3 - Criar arquivos de origem

Agora vamos criar arquivos de origem reais sob o HelloSpringprojeto. Primeiro, precisamos criar um pacote chamadocom.tutorialspoint. Para fazer isso, clique com o botão direito emsrc na seção Package Explorer e siga a opção - New → Package.

Em seguida, vamos criar HelloWorld.java e MainApp.java arquivos no pacote com.tutorialspoint.

Aqui está o conteúdo de HelloWorld.java arquivo -

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

A seguir está o conteúdo do segundo arquivo MainApp.java -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
   }
}

A seguir, dois pontos importantes devem ser observados sobre o programa principal -

  • A primeira etapa é criar um contexto de aplicativo onde usamos a API do framework ClassPathXmlApplicationContext(). Esta API carrega o arquivo de configuração de beans e, eventualmente, com base na API fornecida, ela se encarrega de criar e inicializar todos os objetos, ou seja, os beans mencionados no arquivo de configuração.

  • A segunda etapa é usada para obter o bean necessário usando getBean()método do contexto criado. Este método usa o ID do bean para retornar um objeto genérico, que finalmente pode ser convertido para o objeto real. Depois de ter um objeto, você pode usar esse objeto para chamar qualquer método de classe.

Etapa 4 - Criar Arquivo de Configuração do Bean

Você precisa criar um arquivo de configuração de feijão que é um arquivo XML e atua como um cimento que cola os grãos, ou seja, as classes juntas. Este arquivo precisa ser criado sob osrc diretório como mostrado na imagem a seguir -

Normalmente, os desenvolvedores chamam este arquivo como Beans.xml, mas você é independente para escolher o nome que quiser. Você deve ter certeza de que este arquivo está disponível em CLASSPATH e usar o mesmo nome no aplicativo principal ao criar um contexto de aplicativo, conforme mostrado no arquivo MainApp.java.

O Beans.xml é usado para atribuir IDs exclusivos a diferentes beans e para controlar a criação de objetos com valores diferentes sem impactar nenhum dos arquivos fonte do Spring. Por exemplo, usando o arquivo a seguir, você pode passar qualquer valor para a variável "mensagem" e pode imprimir diferentes valores de mensagem sem afetar os arquivos HelloWorld.java e MainApp.java. Vamos ver como funciona -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

</beans>

Quando o aplicativo Spring é carregado na memória, o Framework faz uso do arquivo de configuração acima para criar todos os beans definidos e atribui a eles um ID único, conforme definido em <bean>tag. Você pode usar<property> tag para passar os valores das diferentes variáveis ​​utilizadas no momento da criação do objeto.

Etapa 5 - Executando o programa

Quando terminar de criar o código-fonte e os arquivos de configuração de beans, você está pronto para esta etapa, que consiste em compilar e executar seu programa. Para fazer isso, mantenha a guia do arquivo MainApp.Java ativa e useRun opção disponível no IDE Eclipse ou use Ctrl + F11 para compilar e executar seu MainAppinscrição. Se tudo estiver bem com o seu aplicativo, isso imprimirá a seguinte mensagem no console do Eclipse IDE -

Your Message : Hello World!

Parabéns, você criou com sucesso seu primeiro aplicativo Spring. Você pode ver a flexibilidade do aplicativo Spring acima alterando o valor da propriedade "mensagem" e mantendo ambos os arquivos de origem inalterados.

O contêiner Spring é o núcleo do Spring Framework. O contêiner irá criar os objetos, conectá-los, configurá-los e gerenciar seu ciclo de vida completo, desde a criação até a destruição. O contêiner Spring usa DI para gerenciar os componentes que compõem um aplicativo. Esses objetos são chamados de Spring Beans, que discutiremos no próximo capítulo.

O contêiner obtém suas instruções sobre quais objetos instanciar, configurar e montar lendo os metadados de configuração fornecidos. Os metadados de configuração podem ser representados por XML, anotações Java ou código Java. O diagrama a seguir representa uma visão de alto nível de como o Spring funciona. O contêiner Spring IoC usa classes Java POJO e metadados de configuração para produzir um sistema ou aplicativo totalmente configurado e executável.

O Spring fornece os dois tipos distintos de contêiner a seguir.

Sr. Não. Recipiente e descrição
1 Spring BeanFactory Container

Este é o contêiner mais simples que fornece o suporte básico para DI e é definido pela interface org.springframework.beans.factory.BeanFactory . O BeanFactory e as interfaces relacionadas, como BeanFactoryAware, InitializingBean, DisposableBean, ainda estão presentes no Spring para fins de compatibilidade com versões anteriores com um grande número de estruturas de terceiros que se integram ao Spring.

2 Spring ApplicationContext Container

Este contêiner adiciona mais funcionalidades específicas da empresa, como a capacidade de resolver mensagens textuais de um arquivo de propriedades e a capacidade de publicar eventos de aplicativo para ouvintes de eventos interessados. Esse contêiner é definido pela interface org.springframework.context.ApplicationContext .

O contêiner ApplicationContext inclui todas as funcionalidades do contêiner BeanFactory , portanto, é geralmente recomendado em vez do BeanFactory . O BeanFactory ainda pode ser usado para aplicativos leves, como dispositivos móveis ou aplicativos baseados em applet, onde o volume de dados e a velocidade são significativos.

Os objetos que formam o backbone de seu aplicativo e que são gerenciados pelo contêiner Spring IoC são chamados beans. Um bean é um objeto instanciado, montado e gerenciado de outra forma por um contêiner Spring IoC. Esses beans são criados com os metadados de configuração que você fornece ao contêiner. Por exemplo, na forma de definições XML <bean /> que você já viu nos capítulos anteriores.

A definição do feijão contém a informação chamada configuration metadata, que é necessário para o contêiner saber o seguinte -

  • Como criar um bean
  • Detalhes do ciclo de vida do Bean
  • Dependências de feijão

Todos os metadados de configuração acima se traduzem em um conjunto das seguintes propriedades que constituem cada definição de bean.

Sr. Não. Propriedades e descrição
1

class

Este atributo é obrigatório e especifica a classe do bean a ser usada para criar o bean.

2

name

Este atributo especifica o identificador do bean exclusivamente. Em metadados de configuração baseados em XML, você usa os atributos id e / ou nome para especificar o (s) identificador (es) de bean.

3

scope

Este atributo especifica o escopo dos objetos criados a partir de uma definição de bean particular e será discutido no capítulo de escopos de bean.

4

constructor-arg

Isso é usado para injetar as dependências e será discutido nos capítulos subsequentes.

5

properties

Isso é usado para injetar as dependências e será discutido nos capítulos subsequentes.

6

autowiring mode

Isso é usado para injetar as dependências e será discutido nos capítulos subsequentes.

7

lazy-initialization mode

Um bean de inicialização lenta informa ao contêiner IoC para criar uma instância de bean quando for solicitada pela primeira vez, em vez de na inicialização.

8

initialization method

Um retorno de chamada a ser chamado logo após todas as propriedades necessárias no bean terem sido definidas pelo contêiner. Isso será discutido no capítulo do ciclo de vida do feijão.

9

destruction method

Um retorno de chamada a ser usado quando o contêiner que contém o bean for destruído. Isso será discutido no capítulo do ciclo de vida do feijão.

Metadados de configuração Spring

O contêiner Spring IoC é totalmente desacoplado do formato no qual esses metadados de configuração são realmente gravados. A seguir estão os três métodos importantes para fornecer metadados de configuração para o Spring Container -

  • Arquivo de configuração baseado em XML.
  • Configuração baseada em anotação
  • Configuração baseada em Java

Você já viu como os metadados de configuração baseados em XML são fornecidos ao contêiner, mas vamos ver outro exemplo de arquivo de configuração baseado em XML com diferentes definições de bean, incluindo inicialização lenta, método de inicialização e método de destruição -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- A simple bean definition -->
   <bean id = "..." class = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with lazy init set on -->
   <bean id = "..." class = "..." lazy-init = "true">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with initialization method -->
   <bean id = "..." class = "..." init-method = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with destruction method -->
   <bean id = "..." class = "..." destroy-method = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- more bean definitions go here -->
   
</beans>

Você pode verificar o exemplo Spring Hello World para entender como definir, configurar e criar Spring Beans.

Discutiremos sobre a configuração baseada em anotação em um capítulo separado. É discutido intencionalmente em um capítulo separado, pois queremos que você entenda alguns outros conceitos importantes do Spring, antes de começar a programar com Spring Dependency Injection com Annotations.

Ao definir um <bean>, você tem a opção de declarar um escopo para aquele bean. Por exemplo, para forçar o Spring a produzir uma nova instância de bean cada vez que uma for necessária, você deve declarar o atributo de escopo do bean comoprototype. Da mesma forma, se você deseja que o Spring retorne a mesma instância de bean cada vez que um for necessário, você deve declarar o atributo de escopo do bean comosingleton.

O Spring Framework suporta os cinco escopos a seguir, três dos quais estão disponíveis apenas se você usar um ApplicationContext compatível com a web.

Sr. Não. Escopo e descrição
1

singleton

Isso define o escopo da definição do bean para uma única instância por contêiner Spring IoC (padrão).

2

prototype

Isso define o escopo de uma única definição de bean para ter qualquer número de instâncias de objeto.

3

request

Isso define o escopo de uma definição de bean para uma solicitação HTTP. Válido apenas no contexto de um Spring ApplicationContext ciente da web.

4

session

Isso define o escopo de uma definição de bean para uma sessão HTTP. Válido apenas no contexto de um Spring ApplicationContext ciente da web.
5

global-session

Isso define o escopo de uma definição de bean para uma sessão HTTP global. Válido apenas no contexto de um Spring ApplicationContext ciente da web.

Neste capítulo, discutiremos sobre os primeiros dois escopos e os três restantes serão discutidos quando discutirmos sobre o Spring ApplicationContext ciente da web.

O escopo singleton

Se um escopo é definido como singleton, o contêiner Spring IoC cria exatamente uma instância do objeto definido por aquela definição de bean. Esta única instância é armazenada em um cache de tais beans singleton e todas as solicitações e referências subsequentes para aquele bean nomeado retornam o objeto em cache.

O escopo padrão é sempre singleton. No entanto, quando você precisa de uma e apenas uma instância de um bean, você pode definir oscope propriedade para singleton no arquivo de configuração do bean, conforme mostrado no seguinte trecho de código -

<!-- A bean definition with singleton scope -->
<bean id = "..." class = "..." scope = "singleton">
   <!-- collaborators and configuration for this bean go here -->
</bean>

Exemplo

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java arquivo -

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

A seguir está o conteúdo do MainApp.java arquivo -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

A seguir está o arquivo de configuração Beans.xml necessário para o escopo singleton -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "singleton">
   </bean>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

Your Message : I'm object A
Your Message : I'm object A

O escopo do protótipo

Se o escopo for definido como protótipo, o contêiner Spring IoC criará uma nova instância de bean do objeto toda vez que uma solicitação para aquele bean específico for feita. Como regra, use o escopo do protótipo para todos os beans com estado completo e o escopo singleton para os beans sem estado.

Para definir um escopo de protótipo, você pode definir o scope propriedade para prototype no arquivo de configuração do bean, conforme mostrado no seguinte trecho de código -

<!-- A bean definition with prototype scope -->
<bean id = "..." class = "..." scope = "prototype">
   <!-- collaborators and configuration for this bean go here -->
</bean>

Exemplo

Vamos ter o Eclipse IDE em funcionamento e seguir as etapas a seguir para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java Arquivo

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

A seguir está o conteúdo do MainApp.java arquivo -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

A seguir está o arquivo de configuração Beans.xml necessário para o escopo do protótipo -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "prototype">
   </bean>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

Your Message : I'm object A
Your Message : null

O ciclo de vida de um bean Spring é fácil de entender. Quando um bean é instanciado, pode ser necessário realizar alguma inicialização para colocá-lo em um estado utilizável. Da mesma forma, quando o bean não é mais necessário e é removido do contêiner, alguma limpeza pode ser necessária.

Embora existam listas das atividades que ocorrem nos bastidores entre o momento da instanciação do bean e sua destruição, este capítulo discutirá apenas dois métodos importantes de retorno de chamada do ciclo de vida do bean, que são necessários no momento da inicialização do bean e sua destruição.

Para definir a configuração e desmontagem de um bean, simplesmente declaramos o <bean> com initmethod e / ou destroy-methodparâmetros. O atributo init-method especifica um método que deve ser chamado no bean imediatamente após a instanciação. Da mesma forma, destroymethod especifica um método que é chamado pouco antes de um bean ser removido do contêiner.

Retornos de chamada de inicialização

A interface org.springframework.beans.factory.InitializingBean especifica um único método -

void afterPropertiesSet() throws Exception;

Assim, você pode simplesmente implementar a interface acima e o trabalho de inicialização pode ser feito dentro do método afterPropertiesSet () da seguinte maneira -

public class ExampleBean implements InitializingBean {
   public void afterPropertiesSet() {
      // do some initialization work
   }
}

No caso de metadados de configuração baseados em XML, você pode usar o init-methodatributo para especificar o nome do método que possui uma assinatura sem argumento nula. Por exemplo -

<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>

A seguir está a definição da classe -

public class ExampleBean {
   public void init() {
      // do some initialization work
   }
}

Retornos de chamada de destruição

A interface org.springframework.beans.factory.DisposableBean especifica um único método -

void destroy() throws Exception;

Assim, você pode simplesmente implementar a interface acima e o trabalho de finalização pode ser feito dentro do método destroy () da seguinte maneira -

public class ExampleBean implements DisposableBean {
   public void destroy() {
      // do some destruction work
   }
}

No caso de metadados de configuração baseados em XML, você pode usar o destroy-methodatributo para especificar o nome do método que possui uma assinatura sem argumento nula. Por exemplo -

<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>

A seguir está a definição da classe -

public class ExampleBean {
   public void destroy() {
      // do some destruction work
   }
}

Se você estiver usando o contêiner IoC do Spring em um ambiente de aplicativo não web; por exemplo, em um ambiente de desktop rich client, você registra um gancho de encerramento com a JVM. Isso garante um desligamento normal e chama os métodos de destruição relevantes em seus beans singleton para que todos os recursos sejam liberados.

É recomendável que você não use os retornos de chamada InitializingBean ou DisposableBean, porque a configuração XML oferece muita flexibilidade em termos de nomenclatura de seu método.

Exemplo

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java arquivo -

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
   public void init(){
      System.out.println("Bean is going through init.");
   }
   public void destroy() {
      System.out.println("Bean will destroy now.");
   }
}

A seguir está o conteúdo do MainApp.javaArquivo. Aqui você precisa registrar um gancho de desligamentoregisterShutdownHook()método que é declarado na classe AbstractApplicationContext. Isso garantirá um desligamento normal e chamará os métodos de destruição relevantes.

package com.tutorialspoint;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}

A seguir está o arquivo de configuração Beans.xml requerido para métodos init e destroy -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" init-method = "init" 
      destroy-method = "destroy">
      <property name = "message" value = "Hello World!"/>
   </bean>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

Bean is going through init.
Your Message : Hello World!
Bean will destroy now.

Métodos padrão de inicialização e destruição

Se você tiver muitos beans com métodos de inicialização e / ou destruição com o mesmo nome, você não precisa declarar init-method e destroy-methodem cada feijão individual. Em vez disso, a estrutura fornece a flexibilidade para configurar tal situação usandodefault-init-method e default-destroy-method atributos no elemento <beans> como segue -

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
   default-init-method = "init" 
   default-destroy-method = "destroy">

   <bean id = "..." class = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>
   
</beans>

o BeanPostProcessor interface define métodos de retorno de chamada que você pode implementar para fornecer sua própria lógica de instanciação, lógica de resolução de dependência, etc. Você também pode implementar alguma lógica personalizada depois que o contêiner Spring terminar de instanciar, configurar e inicializar um bean conectando uma ou mais implementações BeanPostProcessor .

Você pode configurar várias interfaces BeanPostProcessor e pode controlar a ordem em que essas interfaces BeanPostProcessor são executadas definindo o order propriedade desde que o BeanPostProcessor implemente o Ordered interface.

Os BeanPostProcessors operam em instâncias de bean (ou objeto), o que significa que o contêiner Spring IoC instancia uma instância de bean e então as interfaces BeanPostProcessor fazem seu trabalho.

A ApplicationContext detecta automaticamente quaisquer beans que são definidos com a implementação do BeanPostProcessor interface e registra esses beans como pós-processadores, para serem chamados apropriadamente pelo contêiner na criação do bean.

Exemplo

Os exemplos a seguir mostram como escrever, registrar e usar BeanPostProcessors no contexto de um ApplicationContext.

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld , InitHelloWorld e MainApp sob o pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java arquivo -

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
   public void init(){
      System.out.println("Bean is going through init.");
   }
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}

Este é um exemplo muito básico de implementação de BeanPostProcessor, que imprime um nome de bean antes e depois da inicialização de qualquer bean. Você pode implementar uma lógica mais complexa antes e depois de inicializar um bean porque você tem acesso ao objeto do bean dentro de ambos os métodos de pós-processador.

Aqui está o conteúdo de InitHelloWorld.java arquivo -

package com.tutorialspoint;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;

public class InitHelloWorld implements BeanPostProcessor {
   public Object postProcessBeforeInitialization(Object bean, String beanName) 
      throws BeansException {
      
      System.out.println("BeforeInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }
   public Object postProcessAfterInitialization(Object bean, String beanName) 
      throws BeansException {
      
      System.out.println("AfterInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }
}

A seguir está o conteúdo do MainApp.javaArquivo. Aqui você precisa registrar um gancho de desligamentoregisterShutdownHook()método que é declarado na classe AbstractApplicationContext. Isso garante um desligamento normal e chama os métodos de destruição relevantes.

package com.tutorialspoint;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}

A seguir está o arquivo de configuração Beans.xml requerido para métodos init e destroy -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"
      init-method = "init" destroy-method = "destroy">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean class = "com.tutorialspoint.InitHelloWorld" />

</beans>

Quando terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

BeforeInitialization : helloWorld
Bean is going through init.
AfterInitialization : helloWorld
Your Message : Hello World!
Bean will destroy now.

Uma definição de bean pode conter muitas informações de configuração, incluindo argumentos do construtor, valores de propriedade e informações específicas do contêiner, como método de inicialização, nome do método de fábrica estático e assim por diante.

Uma definição de bean filho herda os dados de configuração de uma definição pai. A definição filho pode substituir alguns valores ou adicionar outros, conforme necessário.

A herança da definição do Spring Bean não tem nada a ver com a herança da classe Java, mas o conceito de herança é o mesmo. Você pode definir uma definição de bean pai como um modelo e outros beans filho podem herdar a configuração necessária do bean pai.

Ao usar metadados de configuração baseados em XML, você indica uma definição de bean filho usando o parent atributo, especificando o bean pai como o valor deste atributo.

Exemplo

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld , HelloIndia e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

A seguir está o arquivo de configuração Beans.xmlonde definimos o bean "helloWorld", que possui duas propriedades message1 e message2 . O próximo bean "helloIndia" foi definido como filho do bean "helloWorld" usandoparentatributo. O bean filho herda a propriedade message2 como está, sobrescreve a propriedade message1 e apresenta mais uma propriedade message3 .

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
   </bean>

   <bean id ="helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld">
      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>
</beans>

Aqui está o conteúdo de HelloWorld.java arquivo -

package com.tutorialspoint;

public class HelloWorld {
   private String message1;
   private String message2;

   public void setMessage1(String message){
      this.message1 = message;
   }
   public void setMessage2(String message){
      this.message2 = message;
   }
   public void getMessage1(){
      System.out.println("World Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("World Message2 : " + message2);
   }
}

Aqui está o conteúdo de HelloIndia.java arquivo -

package com.tutorialspoint;

public class HelloIndia {
   private String message1;
   private String message2;
   private String message3;

   public void setMessage1(String message){
      this.message1 = message;
   }
   public void setMessage2(String message){
      this.message2 = message;
   }
   public void setMessage3(String message){
      this.message3 = message;
   }
   public void getMessage1(){
      System.out.println("India Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("India Message2 : " + message2);
   }
   public void getMessage3(){
      System.out.println("India Message3 : " + message3);
   }
}

A seguir está o conteúdo do MainApp.java arquivo -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      
      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
      objA.getMessage1();
      objA.getMessage2();

      HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
      objB.getMessage1();
      objB.getMessage2();
      objB.getMessage3();
   }
}

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!

Se você observou aqui, não passamos a mensagem2 ao criar o bean "helloIndia", mas ela foi aprovada devido à Herança de definição do bean.

Modelo de definição de feijão

Você pode criar um modelo de definição de bean, que pode ser usado por outras definições de bean filho sem colocar muito esforço. Ao definir um modelo de definição de bean, você não deve especificar oclass atributo e deve especificar abstract atributo e deve especificar o atributo abstrato com um valor de true conforme mostrado no seguinte snippet de código -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "beanTeamplate" abstract = "true">
      <property name = "message1" value = "Hello World!"/>
      <property name = "message2" value = "Hello Second World!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>

   <bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">
      <property name = "message1" value = "Hello India!"/>
      <property name = "message3" value = "Namaste India!"/>
   </bean>
   
</beans>

O bean pai não pode ser instanciado sozinho porque está incompleto e também está explicitamente marcado como abstrato . Quando uma definição é abstrata como esta, ela pode ser usada apenas como uma definição de bean de modelo puro que serve como uma definição pai para definições filho.

Cada aplicativo baseado em Java possui alguns objetos que funcionam juntos para apresentar o que o usuário final vê como um aplicativo funcional. Ao escrever um aplicativo Java complexo, as classes do aplicativo devem ser o mais independentes possível de outras classes Java para aumentar a possibilidade de reutilizar essas classes e testá-las independentemente de outras classes durante o teste de unidade. A injeção de dependência (ou às vezes chamada de fiação) ajuda a colar essas classes e, ao mesmo tempo, mantê-las independentes.

Considere que você tem um aplicativo que possui um componente de editor de texto e deseja fornecer uma verificação ortográfica. Seu código padrão seria mais ou menos assim -

public class TextEditor {
   private SpellChecker spellChecker;
   
   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

O que fizemos aqui foi criar uma dependência entre o TextEditor e o SpellChecker. Em um cenário de inversão de controle, em vez disso, faríamos algo assim -

public class TextEditor {
   private SpellChecker spellChecker;
   
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Aqui, o TextEditor não deve se preocupar com a implementação do SpellChecker. O SpellChecker será implementado de forma independente e fornecido ao TextEditor no momento da instanciação do TextEditor. Todo este procedimento é controlado pelo Spring Framework.

Aqui, removemos o controle total do TextEditor e o mantemos em outro lugar (ou seja, arquivo de configuração XML) e a dependência (ou seja, classe SpellChecker) está sendo injetada na classe TextEditor por meio de um Class Constructor. Assim, o fluxo de controle foi "invertido" pela injeção de dependência (DI) porque você delegou dependências efetivamente a algum sistema externo.

O segundo método de injetar dependência é por meio Setter Methodsda classe TextEditor onde criaremos uma instância de SpellChecker. Esta instância será usada para chamar métodos setter para inicializar as propriedades do TextEditor.

Assim, DI existe em duas variantes principais e os dois subcapítulos seguintes cobrirão ambos com exemplos -

Sr. Não. Tipo e descrição de injeção de dependência
1 Injeção de dependência baseada em construtor

A DI baseada em construtor é realizada quando o contêiner invoca um construtor de classe com vários argumentos, cada um representando uma dependência da outra classe.

2 Injeção de dependência baseada em setter

A DI baseada em setter é realizada pelo contêiner chamando métodos setter em seus beans após invocar um construtor sem argumento ou método de fábrica estático sem argumento para instanciar seu bean.

Você pode misturar DI baseada em construtor e baseada em setter, mas é uma boa regra usar argumentos de construtor para dependências obrigatórias e setters para dependências opcionais.

O código é mais limpo com o princípio DI e o desacoplamento é mais eficaz quando os objetos são fornecidos com suas dependências. O objeto não consulta suas dependências e não conhece a localização ou classe das dependências, ao contrário, tudo é cuidado pelo Spring Framework.

Como você sabe, as classes internas do Java são definidas no escopo de outras classes, da mesma forma, inner beanssão beans definidos no escopo de outro bean. Portanto, um elemento <bean /> dentro dos elementos <property /> ou <constructor-arg /> é chamado de bean interno e é mostrado abaixo.

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "outerBean" class = "...">
      <property name = "target">
         <bean id = "innerBean" class = "..."/>
      </property>
   </bean>

</beans>

Exemplo

Vamos ter o Eclipse IDE em funcionamento e seguir as etapas a seguir para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java TextEditor , SpellChecker e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de TextEditor.java arquivo -

package com.tutorialspoint;

public class TextEditor {
   private SpellChecker spellChecker;
   
   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }
   
   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

A seguir está o conteúdo de outro arquivo de classe dependente SpellChecker.java -

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }
}

A seguir está o conteúdo do MainApp.java arquivo -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      TextEditor te = (TextEditor) context.getBean("textEditor");
      te.spellCheck();
   }
}

A seguir está o arquivo de configuração Beans.xml que tem configuração para a injeção baseada em setter, mas usando inner beans -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for textEditor bean using inner bean -->
   <bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
      <property name = "spellChecker">
         <bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"/>
      </property>
   </bean>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.

Você viu como configurar o tipo de dados primitivo usando value referências de atributos e objetos usando refatributo da tag <property> em seu arquivo de configuração Bean. Ambos os casos lidam com a passagem de valor singular para um bean.

Agora, e se você quiser passar valores plurais, como tipos de coleção Java, como Lista, Conjunto, Mapa e Propriedades. Para lidar com a situação, Spring oferece quatro tipos de elementos de configuração de coleção que são os seguintes -

Sr. Não Elemento e descrição
1

<list>

Isso ajuda na fiação, ou seja, injetando uma lista de valores, permitindo duplicatas.

2

<set>

Isso ajuda a conectar um conjunto de valores, mas sem duplicatas.

3

<map>

Isso pode ser usado para injetar uma coleção de pares nome-valor em que nome e valor podem ser de qualquer tipo.

4

<props>

Isso pode ser usado para injetar uma coleção de pares nome-valor onde o nome e o valor são ambos Strings.

Você pode usar <list> ou <set> para conectar qualquer implementação de java.util.Collection ou um array.

Você encontrará duas situações (a) Passando valores diretos da coleção e (b) Passando uma referência de um bean como um dos elementos da coleção.

Exemplo

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java JavaCollection e MainApp no pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de JavaCollection.java arquivo -

package com.tutorialspoint;
import java.util.*;

public class JavaCollection {
   List addressList;
   Set  addressSet;
   Map  addressMap;
   Properties addressProp;

   // a setter method to set List
   public void setAddressList(List addressList) {
      this.addressList = addressList;
   }
   
   // prints and returns all the elements of the list.
   public List getAddressList() {
      System.out.println("List Elements :"  + addressList);
      return addressList;
   }
   
   // a setter method to set Set
   public void setAddressSet(Set addressSet) {
      this.addressSet = addressSet;
   }
   
   // prints and returns all the elements of the Set.
   public Set getAddressSet() {
      System.out.println("Set Elements :"  + addressSet);
      return addressSet;
   }
   
   // a setter method to set Map
   public void setAddressMap(Map addressMap) {
      this.addressMap = addressMap;
   }
   
   // prints and returns all the elements of the Map.
   public Map getAddressMap() {
      System.out.println("Map Elements :"  + addressMap);
      return addressMap;
   }
   
   // a setter method to set Property
   public void setAddressProp(Properties addressProp) {
      this.addressProp = addressProp;
   }
   
   // prints and returns all the elements of the Property.
   public Properties getAddressProp() {
      System.out.println("Property Elements :"  + addressProp);
      return addressProp;
   }
}

A seguir está o conteúdo do MainApp.java arquivo -

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      JavaCollection jc=(JavaCollection)context.getBean("javaCollection");

      jc.getAddressList();
      jc.getAddressSet();
      jc.getAddressMap();
      jc.getAddressProp();
   }
}

A seguir está o arquivo de configuração Beans.xml que tem configuração para todos os tipos de coleções -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for javaCollection -->
   <bean id = "javaCollection" class = "com.tutorialspoint.JavaCollection">
      
      <!-- results in a setAddressList(java.util.List) call -->
      <property name = "addressList">
         <list>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
         </list>
      </property>

      <!-- results in a setAddressSet(java.util.Set) call -->
      <property name = "addressSet">
         <set>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
         </set>
      </property>

      <!-- results in a setAddressMap(java.util.Map) call -->
      <property name = "addressMap">
         <map>
            <entry key = "1" value = "INDIA"/>
            <entry key = "2" value = "Pakistan"/>
            <entry key = "3" value = "USA"/>
            <entry key = "4" value = "USA"/>
         </map>
      </property>
      
      <!-- results in a setAddressProp(java.util.Properties) call -->
      <property name = "addressProp">
         <props>
            <prop key = "one">INDIA</prop>
            <prop key = "one">INDIA</prop>
            <prop key = "two">Pakistan</prop>
            <prop key = "three">USA</prop>
            <prop key = "four">USA</prop>
         </props>
      </property>
   </bean>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

List Elements :[INDIA, Pakistan, USA, USA] 
Set Elements :[INDIA, Pakistan, USA] 
ap Elements :{1 = INDIA, 2 = Pakistan, 3 = USA, 4 = USA} 
Property Elements :{two = Pakistan, one = INDIA, three = USA, four = USA}

Injetando Referências de Feijão

A seguinte definição de Bean ajudará você a entender como injetar referências de bean como um dos elementos da coleção. Mesmo você pode misturar referências e valores, conforme mostrado no seguinte trecho de código -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Bean Definition to handle references and values -->
   <bean id = "..." class = "...">

      <!-- Passing bean reference  for java.util.List -->
      <property name = "addressList">
         <list>
            <ref bean = "address1"/>
            <ref bean = "address2"/>
            <value>Pakistan</value>
         </list>
      </property>
      
      <!-- Passing bean reference  for java.util.Set -->
      <property name = "addressSet">
         <set>
            <ref bean = "address1"/>
            <ref bean = "address2"/>
            <value>Pakistan</value>
         </set>
      </property>
      
      <!-- Passing bean reference  for java.util.Map -->
      <property name = "addressMap">
         <map>
            <entry key = "one" value = "INDIA"/>
            <entry key = "two" value-ref = "address1"/>
            <entry key = "three" value-ref = "address2"/>
         </map>
      </property>
   </bean>

</beans>

Para usar a definição de bean acima, você precisa definir seus métodos setter de forma que eles também possam lidar com referências.

Injetando valores de string nulos e vazios

Se você precisar passar uma string vazia como um valor, você pode passá-la da seguinte maneira -

<bean id = "..." class = "exampleBean">
   <property name = "email" value = ""/>
</bean>

O exemplo anterior é equivalente ao código Java: exampleBean.setEmail ("")

Se você precisa passar um valor NULL, você pode passá-lo da seguinte maneira -

<bean id = "..." class = "exampleBean">
   <property name = "email"><null/></property>
</bean>

O exemplo anterior é equivalente ao código Java: exampleBean.setEmail (null)

Você aprendeu como declarar beans usando o elemento <bean> e injetar <bean> usando os elementos <constructor-arg> e <property> no arquivo de configuração XML.

O recipiente Spring pode autowire relacionamentos entre beans colaborativos sem usar os elementos <constructor-arg> e <property>, o que ajuda a reduzir a quantidade de configuração XML que você escreve para um grande aplicativo baseado em Spring.

Modos de fiação automática

A seguir estão os modos de autowiring, que podem ser usados ​​para instruir o contêiner Spring a usar autowiring para injeção de dependência. Você usa o atributo autowire do elemento <bean /> para especificarautowire modo para uma definição de bean.

Sr. Não Modo e descrição
1 no

Esta é a configuração padrão, o que significa sem autowiring e você deve usar uma referência explícita de bean para a fiação. Você não tem nada a fazer de especial para esta fiação. Isso é o que você já viu no capítulo Injeção de Dependências.

2 byName

Autowiring por nome de propriedade. O Spring container examina as propriedades dos beans nos quais o atributo autowire está definido como byName no arquivo de configuração XML. Em seguida, ele tenta combinar e conectar suas propriedades aos beans definidos pelos mesmos nomes no arquivo de configuração.

3 por tipo

Autowiring por tipo de dados de propriedade. O contêiner Spring examina as propriedades dos beans nos quais o atributo autowire está definido como byType no arquivo de configuração XML. Em seguida, ele tenta combinar e conectar uma propriedade se fortypecorresponde exatamente a um dos nomes de beans no arquivo de configuração. Se mais de um desses beans existir, uma exceção fatal será lançada.

4 constructor

Similar to byType, but type applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.

5 autodetect

Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType.

You can use byType or constructor autowiring mode to wire arrays and other typed-collections.

Limitations with autowiring

Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing for developers to use it to wire only one or two bean definitions. Though, autowiring can significantly reduce the need to specify properties or constructor arguments but you should consider the limitations and disadvantages of autowiring before using them.

Sr.No. Limitations & Description
1

Overriding possibility

You can still specify dependencies using <constructor-arg> and <property> settings which will always override autowiring.

2

Primitive data types

You cannot autowire so-called simple properties such as primitives, Strings, and Classes.

3

Confusing nature

Autowiring is less exact than explicit wiring, so if possible prefer using explict wiring.

Starting from Spring 2.5 it became possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration.

Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.

Annotation wiring is not turned on in the Spring container by default. So, before we can use annotation-based wiring, we will need to enable it in our Spring configuration file. So consider the following configuration file in case you want to use any annotation in your Spring application.

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context = "http://www.springframework.org/schema/context"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

Once <context:annotation-config/> is configured, you can start annotating your code to indicate that Spring should automatically wire values into properties, methods, and constructors. Let us look at a few important annotations to understand how they work −

Sr.No. Annotation & Description
1 @Required

The @Required annotation applies to bean property setter methods.

2 @Autowired

The @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties.

3 @Qualifier

The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired.

4 JSR-250 Annotations

Spring supports JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations.

So far you have seen how we configure Spring beans using XML configuration file. If you are comfortable with XML configuration, then it is really not required to learn how to proceed with Java-based configuration as you are going to achieve the same result using either of the configurations available.

Java-based configuration option enables you to write most of your Spring configuration without XML but with the help of few Java-based annotations explained in this chapter.

@Configuration & @Bean Annotations

Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. The simplest possible @Configuration class would be as follows −

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

The above code will be equivalent to the following XML configuration −

<beans>
   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" />
</beans>

Here, the method name is annotated with @Bean works as bean ID and it creates and returns the actual bean. Your configuration class can have a declaration for more than one @Bean. Once your configuration classes are defined, you can load and provide them to Spring container using AnnotationConfigApplicationContext as follows −

public static void main(String[] args) {
   ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
   
   HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
   helloWorld.setMessage("Hello World!");
   helloWorld.getMessage();
}

You can load various configuration classes as follows −

public static void main(String[] args) {
   AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

   ctx.register(AppConfig.class, OtherConfig.class);
   ctx.register(AdditionalConfig.class);
   ctx.refresh();

   MyService myService = ctx.getBean(MyService.class);
   myService.doStuff();
}

Example

Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −

Steps Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org.
4 Create Java classes HelloWorldConfig, HelloWorld and MainApp under the com.tutorialspoint package.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of HelloWorldConfig.java file

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

Here is the content of HelloWorld.java file

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

Following is the content of the MainApp.java file

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext ctx = 
         new AnnotationConfigApplicationContext(HelloWorldConfig.class);
   
      HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
      helloWorld.setMessage("Hello World!");
      helloWorld.getMessage();
   }
}

Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −

Your Message : Hello World!

Injecting Bean Dependencies

When @Beans have dependencies on one another, expressing that the dependency is as simple as having one bean method calling another as follows −

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class AppConfig {
   @Bean
   public Foo foo() {
      return new Foo(bar());
   }
   @Bean
   public Bar bar() {
      return new Bar();
   }
}

Here, the foo bean receives a reference to bar via the constructor injection. Now let us look at another working example.

Example

Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −

Steps Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org.
4 Create Java classes TextEditorConfig, TextEditor, SpellChecker and MainApp under the com.tutorialspoint package.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of TextEditorConfig.java file

package com.tutorialspoint;
import org.springframework.context.annotation.*;

@Configuration
public class TextEditorConfig {
   @Bean 
   public TextEditor textEditor(){
      return new TextEditor( spellChecker() );
   }

   @Bean 
   public SpellChecker spellChecker(){
      return new SpellChecker( );
   }
}

Here is the content of TextEditor.java file

package com.tutorialspoint;

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor(SpellChecker spellChecker){
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

Following is the content of another dependent class file SpellChecker.java

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }
}

Following is the content of the MainApp.java file

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext ctx = 
         new AnnotationConfigApplicationContext(TextEditorConfig.class);

      TextEditor te = ctx.getBean(TextEditor.class);
      te.spellCheck();
   }
}

Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

The @Import Annotation

The @Import annotation allows for loading @Bean definitions from another configuration class. Consider a ConfigA class as follows −

@Configuration
public class ConfigA {
   @Bean
   public A a() {
      return new A(); 
   }
}

You can import above Bean declaration in another Bean Declaration as follows −

@Configuration
@Import(ConfigA.class)
public class ConfigB {
   @Bean
   public B b() {
      return new B(); 
   }
}

Now, rather than needing to specify both ConfigA.class and ConfigB.class when instantiating the context, only ConfigB needs to be supplied as follows −

public static void main(String[] args) {
   ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
   
   // now both beans A and B will be available...
   A a = ctx.getBean(A.class);
   B b = ctx.getBean(B.class);
}

Callbacks do ciclo de vida

A anotação @Bean suporta a especificação de métodos de retorno de chamada de inicialização e destruição arbitrários, bem como os atributos init-method e destroy-method do Spring XML no elemento bean -

public class Foo {
   public void init() {
      // initialization logic
   }
   public void cleanup() {
      // destruction logic
   }
}
@Configuration
public class AppConfig {
   @Bean(initMethod = "init", destroyMethod = "cleanup" )
   public Foo foo() {
      return new Foo();
   }
}

Especificando o Escopo do Feijão

O escopo padrão é singleton, mas você pode substituí-lo pela anotação @Scope da seguinte maneira -

@Configuration
public class AppConfig {
   @Bean
   @Scope("prototype")
   public Foo foo() {
      return new Foo();
   }
}

Você viu em todos os capítulos que o cerne do Spring é o ApplicationContext, que gerencia o ciclo de vida completo dos grãos. O ApplicationContext publica certos tipos de eventos ao carregar os beans. Por exemplo, um ContextStartedEvent é publicado quando o contexto é iniciado e ContextStoppedEvent é publicado quando o contexto é interrompido.

Manipulação no evento ApplicationContext é fornecido através do ApplicationEvent classe e ApplicationListener interface. Portanto, se um bean implementa o ApplicationListener , toda vez que um ApplicationEvent é publicado no ApplicationContext, esse bean é notificado.

Spring fornece os seguintes eventos padrão -

Sr. Não. Eventos e descrição integrados da mola
1

ContextRefreshedEvent

Este evento é publicado quando o ApplicationContext é inicializado ou atualizado. Isso também pode ser gerado usando o método refresh () na interface ConfigurableApplicationContext .

2

ContextStartedEvent

Este evento é publicado quando o ApplicationContext é iniciado usando o método start () na interface ConfigurableApplicationContext . Você pode pesquisar seu banco de dados ou reiniciar qualquer aplicativo interrompido após receber este evento.

3

ContextStoppedEvent

Este evento é publicado quando o ApplicationContext é interrompido usando o método stop () na interface ConfigurableApplicationContext . Você pode fazer o trabalho de limpeza necessário após receber este evento.

4

ContextClosedEvent

Este evento é publicado quando o ApplicationContext é fechado usando o método close () na interface ConfigurableApplicationContext . Um contexto fechado chega ao fim de sua vida; ele não pode ser atualizado ou reiniciado.

5

RequestHandledEvent

Este é um evento específico da web que informa a todos os beans que uma solicitação HTTP foi atendida.

O tratamento de eventos do Spring é de thread único, portanto, se um evento for publicado, até e a menos que todos os receptores recebam a mensagem, os processos são bloqueados e o fluxo não continuará. Portanto, deve-se tomar cuidado ao projetar seu aplicativo se o tratamento de eventos for usado.

Ouvindo eventos de contexto

Para ouvir um evento de contexto, um bean deve implementar a interface ApplicationListener , que possui apenas um métodoonApplicationEvent(). Então, vamos escrever um exemplo para ver como os eventos se propagam e como você pode colocar seu código para fazer a tarefa necessária com base em certos eventos.

Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -

Degrau Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie classes Java HelloWorld , CStartEventHandler , CStopEventHandler e MainApp sob o pacote com.tutorialspoint .
4 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
5 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java Arquivo

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

A seguir está o conteúdo do CStartEventHandler.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;

public class CStartEventHandler 
   implements ApplicationListener<ContextStartedEvent>{

   public void onApplicationEvent(ContextStartedEvent event) {
      System.out.println("ContextStartedEvent Received");
   }
}

A seguir está o conteúdo do CStopEventHandler.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;

public class CStopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{

   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}

A seguir está o conteúdo do MainApp.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
         new ClassPathXmlApplicationContext("Beans.xml");

      // Let us raise a start event.
      context.start();
	  
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();

      // Let us raise a stop event.
      context.stop();
   }
}

A seguir está o arquivo de configuração Beans.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean id = "cStartEventHandler" class = "com.tutorialspoint.CStartEventHandler"/>
   <bean id = "cStopEventHandler" class = "com.tutorialspoint.CStopEventHandler"/>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received

Se desejar, você pode publicar seus próprios eventos personalizados e, posteriormente, capturar os mesmos para realizar qualquer ação contra esses eventos personalizados. Se você estiver interessado em escrever seus próprios eventos personalizados, pode verificar Eventos personalizados na primavera.

Existem várias etapas a serem seguidas para escrever e publicar seus próprios eventos personalizados. Siga as instruções fornecidas neste capítulo para escrever, publicar e lidar com eventos Spring personalizados.

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrcpasta no projeto criado. Todas as classes serão criadas neste pacote.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Crie uma classe de evento, CustomEvent , estendendoApplicationEvent. Esta classe deve definir um construtor padrão que deve herdar o construtor da classe ApplicationEvent.
4 Depois que sua classe de evento é definida, você pode publicá-la de qualquer classe, digamos EventClassPublisher que implementa ApplicationEventPublisherAware . Você também precisará declarar essa classe no arquivo de configuração XML como um bean para que o contêiner possa identificar o bean como um publicador de evento porque ele implementa a interface ApplicationEventPublisherAware.
5 Um evento publicado pode ser tratado em uma classe, digamos EventClassHandler, que implementa a interface ApplicationListener e implementa o método onApplicationEvent para o evento personalizado.
6 Crie o arquivo de configuração de beans Beans.xml sob osrce uma classe MainApp que funcionará como um aplicativo Spring.
7 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de CustomEvent.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent{
   public CustomEvent(Object source) {
      super(source);
   }
   public String toString(){
      return "My Custom Event";
   }
}

A seguir está o conteúdo do CustomEventPublisher.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

public class CustomEventPublisher implements ApplicationEventPublisherAware {
   private ApplicationEventPublisher publisher;
   
   public void setApplicationEventPublisher (ApplicationEventPublisher publisher) {
      this.publisher = publisher;
   }
   public void publish() {
      CustomEvent ce = new CustomEvent(this);
      publisher.publishEvent(ce);
   }
}

A seguir está o conteúdo do CustomEventHandler.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;

public class CustomEventHandler implements ApplicationListener<CustomEvent> {
   public void onApplicationEvent(CustomEvent event) {
      System.out.println(event.toString());
   }
}

A seguir está o conteúdo do MainApp.java Arquivo

package com.tutorialspoint;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
         new ClassPathXmlApplicationContext("Beans.xml");
	  
      CustomEventPublisher cvp = 
         (CustomEventPublisher) context.getBean("customEventPublisher");
      
      cvp.publish();  
      cvp.publish();
   }
}

A seguir está o arquivo de configuração Beans.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "customEventHandler" class = "com.tutorialspoint.CustomEventHandler"/>
   <bean id = "customEventPublisher" class = "com.tutorialspoint.CustomEventPublisher"/>

</beans>

Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, ele imprimirá a seguinte mensagem -

y Custom Event
y Custom Event

Um dos principais componentes do Spring Framework é o Aspect oriented programming (AOP)estrutura. A Programação Orientada a Aspectos envolve a divisão da lógica do programa em partes distintas, chamadas de preocupações. As funções que abrangem vários pontos de um aplicativo são chamadascross-cutting concernse essas questões transversais são conceitualmente separadas da lógica de negócios do aplicativo. Existem vários bons exemplos comuns de aspectos como registro, auditoria, transações declarativas, segurança, armazenamento em cache, etc.

A principal unidade de modularidade em OOP é a classe, enquanto em AOP a unidade de modularidade é o aspecto. A injeção de dependência ajuda a desacoplar seus objetos de aplicativo uns dos outros e o AOP ajuda a desacoplar interesses transversais dos objetos que eles afetam. AOP é como gatilhos em linguagens de programação como Perl, .NET, Java e outras.

O módulo Spring AOP fornece interceptores para interceptar um aplicativo. Por exemplo, quando um método é executado, você pode adicionar funcionalidade extra antes ou depois da execução do método.

Terminologias AOP

Antes de começarmos a trabalhar com AOP, vamos nos familiarizar com os conceitos e terminologia de AOP. Esses termos não são específicos do Spring, mas estão relacionados ao AOP.

Sr. Não Termos e Descrição
1

Aspect

Este é um módulo que possui um conjunto de APIs que fornecem requisitos transversais. Por exemplo, um módulo de registro seria chamado de aspecto AOP para registro. Um aplicativo pode ter vários aspectos, dependendo do requisito.

2

Join point

Isso representa um ponto em seu aplicativo onde você pode inserir o aspecto AOP. Você também pode dizer que é o lugar real no aplicativo onde uma ação será realizada usando a estrutura Spring AOP.

3

Advice

Esta é a ação real a ser realizada antes ou depois da execução do método. Este é um trecho real de código que é invocado durante a execução do programa pelo framework Spring AOP.

4

Pointcut

Este é um conjunto de um ou mais pontos de junção onde um conselho deve ser executado. Você pode especificar pontos de corte usando expressões ou padrões, como veremos em nossos exemplos de AOP.

5

Introduction

Uma introdução permite adicionar novos métodos ou atributos às classes existentes.

6

Target object

O objeto sendo aconselhado por um ou mais aspectos. Este objeto será sempre um objeto proxy, também conhecido como objeto aconselhado.

7

Weaving

Tecelagem é o processo de vincular aspectos a outros tipos de aplicativos ou objetos para criar um objeto recomendado. Isso pode ser feito em tempo de compilação, tempo de carregamento ou tempo de execução.

Tipos de conselhos

Aspectos de primavera podem funcionar com cinco tipos de conselhos mencionados a seguir -

Sr. Não Conselhos e descrição
1

before

Execute o conselho antes da execução do método a.

2

after

Execute o conselho após a execução do método, independentemente de seu resultado.

3

after-returning

Execute o conselho após a execução do método a apenas se o método for concluído com êxito.

4

after-throwing

Execute o conselho após a execução de um método apenas se o método for encerrado lançando uma exceção.

5

around

Execute o conselho antes e depois de invocar o método recomendado.

Implementação de aspectos personalizados

Spring apóia o @AspectJ annotation style abordagem e o schema-basedabordagem para implementar aspectos personalizados. Essas duas abordagens foram explicadas em detalhes nas seções a seguir.

Sr. Não Abordagem e descrição
1 Baseado em esquema XML

Aspectos são implementados usando classes regulares junto com configuração baseada em XML.

2 Baseado em @AspectJ

@AspectJ refere-se a um estilo de declaração de aspectos como classes Java regulares anotadas com anotações Java 5.

Ao trabalhar com o banco de dados usando JDBC simples e antigo, torna-se complicado escrever código desnecessário para lidar com exceções, abrindo e fechando conexões de banco de dados, etc. No entanto, o Spring JDBC Framework cuida de todos os detalhes de baixo nível a partir da abertura da conexão, prepare e executar a instrução SQL, processar exceções, lidar com transações e, finalmente, fechar a conexão.

Portanto, o que você precisa fazer é apenas definir os parâmetros de conexão e especificar a instrução SQL a ser executada e fazer o trabalho necessário para cada iteração enquanto busca dados do banco de dados.

O Spring JDBC fornece várias abordagens e classes correspondentes diferentes para fazer a interface com o banco de dados. Vou usar a abordagem clássica e mais popular, que usaJdbcTemplateclasse do framework. Esta é a classe de estrutura central que gerencia toda a comunicação do banco de dados e tratamento de exceções.

Classe JdbcTemplate

A classe JDBC Template executa consultas SQL, atualiza instruções, armazena chamadas de procedimento, realiza iteração em ResultSets e extrai valores de parâmetro retornados. Ele também captura exceções JDBC e as traduz para a hierarquia de exceção genérica e mais informativa definida no pacote org.springframework.dao.

As instâncias da classe JdbcTemplate são threadsafe depois de configuradas. Portanto, você pode configurar uma única instância de um JdbcTemplate e, em seguida, injetar com segurança essa referência compartilhada em vários DAOs.

Uma prática comum ao usar a classe JDBC Template é configurar um DataSource em seu arquivo de configuração Spring e, em seguida, injetar em dependência esse bean DataSource compartilhado em suas classes DAO, e o JdbcTemplate é criado no setter para o DataSource.

Configurando a fonte de dados

Vamos criar uma tabela de banco de dados Student em nosso banco de dados TEST. Presumimos que você esteja trabalhando com banco de dados MySQL; se trabalhar com qualquer outro banco de dados, você pode alterar suas consultas DDL e SQL de acordo.

CREATE TABLE Student(
   ID   INT NOT NULL AUTO_INCREMENT,
   NAME VARCHAR(20) NOT NULL,
   AGE  INT NOT NULL,
   PRIMARY KEY (ID)
);

Agora precisamos fornecer uma fonte de dados ao modelo JDBC para que ele possa se configurar para obter acesso ao banco de dados. Você pode configurar o DataSource no arquivo XML com um trecho de código, conforme mostrado no seguinte trecho de código -

<bean id = "dataSource" 
   class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
   <property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
   <property name = "username" value = "root"/>
   <property name = "password" value = "password"/>
</bean>

Objeto de acesso a dados (DAO)

DAO significa Data Access Object, que é comumente usado para interação de banco de dados. Os DAOs existem para fornecer um meio de ler e gravar dados no banco de dados e devem expor essa funcionalidade por meio de uma interface pela qual o restante do aplicativo os acessará.

O suporte DAO no Spring torna mais fácil trabalhar com tecnologias de acesso a dados como JDBC, Hibernate, JPA ou JDO de maneira consistente.

Execução de instruções SQL

Vamos ver como podemos realizar a operação CRUD (Criar, Ler, Atualizar e Excluir) em tabelas de banco de dados usando o objeto SQL e JDBC Template.

Querying for an integer

String SQL = "select count(*) from Student";
int rowCount = jdbcTemplateObject.queryForInt( SQL );

Querying for a long

String SQL = "select count(*) from Student";
long rowCount = jdbcTemplateObject.queryForLong( SQL );

A simple query using a bind variable

String SQL = "select age from Student where id = ?";
int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});

Querying for a String

String SQL = "select name from Student where id = ?";
String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);

Querying and returning an object

String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(
   SQL, new Object[]{10}, new StudentMapper());

public class StudentMapper implements RowMapper<Student> {
   public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
      Student student = new Student();
      student.setID(rs.getInt("id"));
      student.setName(rs.getString("name"));
      student.setAge(rs.getInt("age"));
      
      return student;
   }
}

Querying and returning multiple objects

String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(
   SQL, new StudentMapper());

public class StudentMapper implements RowMapper<Student> {
   public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
      Student student = new Student();
      student.setID(rs.getInt("id"));
      student.setName(rs.getString("name"));
      student.setAge(rs.getInt("age"));
      
      return student;
   }
}

Inserting a row into the table

String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );

Updating a row into the table

String SQL = "update Student set name = ? where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );

Deleting a row from the table

String SQL = "delete Student where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{20} );

Executando declarações DDL

Você pode usar o execute(..)método de jdbcTemplate para executar quaisquer instruções SQL ou instruções DDL. A seguir está um exemplo para usar a instrução CREATE para criar uma tabela -

String SQL = "CREATE TABLE Student( " +
   "ID   INT NOT NULL AUTO_INCREMENT, " +
   "NAME VARCHAR(20) NOT NULL, " +
   "AGE  INT NOT NULL, " +
   "PRIMARY KEY (ID));"

jdbcTemplateObject.execute( SQL );

Exemplos de framework Spring JDBC

Com base nos conceitos acima, vamos verificar alguns exemplos importantes que o ajudarão a entender o uso da estrutura JDBC no Spring -

Sr. Não. Exemplo e descrição
1 Exemplo de Spring JDBC

Este exemplo explicará como escrever um aplicativo Spring simples baseado em JDBC.

2 Procedimento SQL armazenado na primavera

Aprenda como chamar o procedimento armazenado SQL ao usar JDBC no Spring.

Uma transação de banco de dados é uma sequência de ações que são tratadas como uma única unidade de trabalho. Essas ações devem ser totalmente concluídas ou não terão efeito algum. O gerenciamento de transações é uma parte importante do aplicativo corporativo orientado para RDBMS para garantir a integridade e consistência dos dados. O conceito de transações pode ser descrito com as seguintes quatro propriedades principais descritas comoACID -

  • Atomicity - Uma transação deve ser tratada como uma única unidade de operação, o que significa que toda a sequência de operações foi bem ou malsucedida.

  • Consistency - Isso representa a consistência da integridade referencial do banco de dados, chaves primárias exclusivas nas tabelas, etc.

  • Isolation- Pode haver muitos processamento de transações com o mesmo conjunto de dados ao mesmo tempo. Cada transação deve ser isolada de outras para evitar a corrupção de dados.

  • Durability - Assim que uma transação for concluída, os resultados dessa transação devem se tornar permanentes e não podem ser apagados do banco de dados devido a falha do sistema.

Um sistema de banco de dados RDBMS real garantirá todas as quatro propriedades para cada transação. A visão simplista de uma transação emitida para o banco de dados usando SQL é a seguinte -

  • Comece a transação usando o comando begin transaction .

  • Execute várias operações de exclusão, atualização ou inserção usando consultas SQL.

  • Se todas as operações forem bem-sucedidas, execute a confirmação, caso contrário, reverta todas as operações.

O Spring framework fornece uma camada abstrata sobre diferentes APIs de gerenciamento de transações subjacentes. O suporte a transações do Spring visa fornecer uma alternativa às transações EJB, adicionando recursos de transação aos POJOs. O Spring oferece suporte ao gerenciamento de transações programáticas e declarativas. Os EJBs requerem um servidor de aplicativos, mas o gerenciamento de transações Spring pode ser implementado sem a necessidade de um servidor de aplicativos.

Transações locais vs. globais

As transações locais são específicas para um único recurso transacional, como uma conexão JDBC, enquanto as transações globais podem abranger vários recursos transacionais como transações em um sistema distribuído.

O gerenciamento de transações locais pode ser útil em um ambiente de computação centralizado onde os componentes e recursos do aplicativo estão localizados em um único site, e o gerenciamento de transações envolve apenas um gerenciador de dados local em execução em uma única máquina. As transações locais são mais fáceis de serem implementadas.

O gerenciamento de transações globais é necessário em um ambiente de computação distribuído, onde todos os recursos são distribuídos em vários sistemas. Nesse caso, o gerenciamento de transações precisa ser feito em nível local e global. Uma transação distribuída ou global é executada em vários sistemas, e sua execução requer coordenação entre o sistema de gerenciamento de transação global e todos os gerenciadores de dados locais de todos os sistemas envolvidos.

Programático vs. Declarativo

Spring suporta dois tipos de gerenciamento de transações -

  • Gerenciamento de transação programática - Isso significa que você deve gerenciar a transação com a ajuda da programação. Isso proporciona extrema flexibilidade, mas é difícil de manter.

  • Gerenciamento declarativo de transações - isso significa que você separa o gerenciamento de transações do código de negócios. Você só usa anotações ou configuração baseada em XML para gerenciar as transações.

O gerenciamento de transações declarativas é preferível ao gerenciamento de transações programáticas, embora seja menos flexível do que o gerenciamento de transações programáticas, que permite controlar as transações por meio de seu código. Mas, como uma espécie de preocupação transversal, o gerenciamento de transações declarativas pode ser modularizado com a abordagem AOP. O Spring oferece suporte ao gerenciamento de transações declarativas por meio da estrutura Spring AOP.

Abstrações de transações de primavera

A chave para a abstração da transação Spring é definida pela interface org.springframework.transaction.PlatformTransactionManager , que é a seguinte -

public interface PlatformTransactionManager {
   TransactionStatus getTransaction(TransactionDefinition definition);
   throws TransactionException;
   
   void commit(TransactionStatus status) throws TransactionException;
   void rollback(TransactionStatus status) throws TransactionException;
}

Sr. Não Método e Descrição
1

TransactionStatus getTransaction(TransactionDefinition definition)

Este método retorna uma transação atualmente ativa ou cria uma nova, de acordo com o comportamento de propagação especificado.

2

void commit(TransactionStatus status)

Este método confirma a transação dada, em relação ao seu status.

3

void rollback(TransactionStatus status)

Este método executa uma reversão da transação fornecida.

O TransactionDefinition é a interface principal do suporte à transação no Spring e é definido da seguinte forma -

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

Sr. Não Método e Descrição
1

int getPropagationBehavior()

Este método retorna o comportamento de propagação. O Spring oferece todas as opções de propagação de transação familiares do EJB CMT.

2

int getIsolationLevel()

Este método retorna o grau em que esta transação está isolada do trabalho de outras transações.

3

String getName()

Este método retorna o nome desta transação.

4

int getTimeout()

Este método retorna o tempo em segundos em que a transação deve ser concluída.

5

boolean isReadOnly()

Este método retorna se a transação é somente leitura.

A seguir estão os valores possíveis para o nível de isolamento -

Sr. Não Isolamento e descrição
1

TransactionDefinition.ISOLATION_DEFAULT

Este é o nível de isolamento padrão.

2

TransactionDefinition.ISOLATION_READ_COMMITTED

Indica que leituras sujas são evitadas; leituras não repetíveis e leituras fantasmas podem ocorrer.

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

Indica que podem ocorrer leituras sujas, leituras não repetíveis e leituras fantasmas.

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

Indica que leituras sujas e leituras não repetíveis são evitadas; podem ocorrer leituras fantasmas.

5

TransactionDefinition.ISOLATION_SERIALIZABLE

Indica que leituras sujas, leituras não repetíveis e leituras fantasmas são evitadas.

A seguir estão os valores possíveis para os tipos de propagação -

Sr. Não. Propagação e descrição
1

TransactionDefinition.PROPAGATION_MANDATORY

Suporta uma transação atual; lança uma exceção se nenhuma transação atual existir.

2

TransactionDefinition.PROPAGATION_NESTED

É executado dentro de uma transação aninhada se existir uma transação atual.

3

TransactionDefinition.PROPAGATION_NEVER

Não suporta uma transação atual; lança uma exceção se houver uma transação atual.

4

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

Não suporta uma transação atual; em vez disso, sempre execute de forma não transacional.

5

TransactionDefinition.PROPAGATION_REQUIRED

Suporta uma transação atual; cria um novo se não houver nenhum.

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW

Cria uma nova transação, suspendendo a transação atual, se houver.

7

TransactionDefinition.PROPAGATION_SUPPORTS

Suporta uma transação atual; é executado de forma não transacional, se não houver nenhum.

8

TransactionDefinition.TIMEOUT_DEFAULT

Usa o tempo limite padrão do sistema de transação subjacente ou nenhum se os tempos limite não forem suportados.

A interface TransactionStatus fornece uma maneira simples para o código transacional controlar a execução da transação e consultar o status da transação.

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

Sr. Não. Método e Descrição
1

boolean hasSavepoint()

Este método retorna se esta transação carrega internamente um ponto de salvamento, ou seja, foi criada como uma transação aninhada com base em um ponto de salvamento.

2

boolean isCompleted()

Este método retorna se a transação foi concluída, ou seja, se ela já foi confirmada ou revertida.

3

boolean isNewTransaction()

Este método retorna verdadeiro caso a transação presente seja nova.

4

boolean isRollbackOnly()

Este método retorna se a transação foi marcada como somente rollback.

5

void setRollbackOnly()

Este método define a transação como somente rollback.

A estrutura Spring Web MVC fornece arquitetura Model-View-Controller (MVC) e componentes prontos que podem ser usados ​​para desenvolver aplicativos da web flexíveis e fracamente acoplados. O padrão MVC resulta na separação dos diferentes aspectos do aplicativo (lógica de entrada, lógica de negócios e lógica de IU), enquanto fornece um acoplamento fraco entre esses elementos.

  • o Model encapsula os dados do aplicativo e, em geral, eles consistirão em POJO.

  • o View é responsável por renderizar os dados do modelo e, em geral, gera saída HTML que o navegador do cliente pode interpretar.

  • o Controller é responsável por processar as solicitações do usuário e construir um modelo apropriado e passa-o para a visualização para renderização.

O DispatcherServlet

A estrutura do Spring Web model-view-controller (MVC) é projetada em torno de um DispatcherServlet que trata todas as solicitações e respostas HTTP. O fluxo de trabalho de processamento de solicitação do Spring Web MVC DispatcherServlet é ilustrado no diagrama a seguir -

A seguir está a sequência de eventos correspondentes a uma solicitação HTTP de entrada para DispatcherServlet -

  • Depois de receber um pedido HTTP, DispatcherServlet consulta o HandlerMapping para chamar o Controlador apropriado .

  • O Controlador recebe a solicitação e chama os métodos de serviço apropriados com base no método GET ou POST usado. O método de serviço configurará os dados do modelo com base na lógica de negócios definida e retorna o nome da visualização para o DispatcherServlet .

  • O DispatcherServlet obterá ajuda de ViewResolver para selecionar a visualização definida para a solicitação.

  • Depois que a visualização é finalizada, o DispatcherServlet passa os dados do modelo para a visualização que é finalmente renderizada no navegador.

Todos os componentes mencionados acima, ou seja, HandlerMapping, Controller e ViewResolver são partes do WebApplicationContext w, que é uma extensão do ApplicationContext simples com alguns recursos extras necessários para aplicativos da web.

Configuração Requerida

Você precisa mapear as solicitações que deseja que o DispatcherServlet manipule, usando um mapeamento de URL noweb.xmlArquivo. A seguir está um exemplo para mostrar declaração e mapeamento paraHelloWeb Exemplo de DispatcherServlet -

<web-app id = "WebApp_ID" version = "2.4"
   xmlns = "http://java.sun.com/xml/ns/j2ee" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
   <display-name>Spring MVC Application</display-name>
   
   <servlet>
      <servlet-name>HelloWeb</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>HelloWeb</servlet-name>
      <url-pattern>*.jsp</url-pattern>
   </servlet-mapping>

</web-app>

o web.xmlO arquivo será mantido no diretório WebContent / WEB-INF de seu aplicativo da web. Após a inicialização deHelloWeb DispatcherServlet, a estrutura tentará carregar o contexto do aplicativo a partir de um arquivo denominado [servlet-name]-servlet.xmllocalizado no diretório WebContent / WEB-INF do aplicativo. Neste caso, nosso arquivo seráHelloWebservlet.xml.

A seguir, a tag <servlet-mapping> indica quais URLs serão tratados por qual DispatcherServlet. Aqui, todas as solicitações HTTP que terminam com.jsp será tratado pelo HelloWeb DispatcherServlet.

Se não quiser usar o nome do arquivo padrão como [servlet-name] -servlet.xml e o local padrão como WebContent / WEB-INF , você pode personalizar o nome e o local desse arquivo adicionando o ouvinte de servlet ContextLoaderListener em seu arquivo web.xml como segue -

<web-app...>

   <!-------- DispatcherServlet definition goes here----->
   ....
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
   </context-param>

   <listener>
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
   </listener>
   
</web-app>

Agora, vamos verificar a configuração necessária para HelloWeb-servlet.xmlarquivo, colocado no diretório WebContent / WEB-INF de seu aplicativo da web -

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:context = "http://www.springframework.org/schema/context"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans     
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:component-scan base-package = "com.tutorialspoint" />

   <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name = "prefix" value = "/WEB-INF/jsp/" />
      <property name = "suffix" value = ".jsp" />
   </bean>

</beans>

A seguir estão os pontos importantes sobre HelloWeb-servlet.xml arquivo -

  • O arquivo [servlet-name] -servlet.xml será usado para criar os beans definidos, substituindo as definições de quaisquer beans definidos com o mesmo nome no escopo global.

  • A tag <context: component-scan ...> será usada para ativar o recurso de varredura de anotação Spring MVC, que permite fazer uso de anotações como @Controller e @RequestMapping etc.

  • O InternalResourceViewResolver terá regras definidas para resolver os nomes das visualizações. De acordo com a regra definida acima, uma visão lógica chamadahelloé delegado a uma implementação de visualização localizada em /WEB-INF/jsp/hello.jsp .

A seção a seguir mostrará como criar seus componentes reais, ou seja, Controlador, Modelo e Visualização.

Definindo um controlador

O DispatcherServlet delega a solicitação aos controladores para executar a funcionalidade específica a ele. o@Controllera anotação indica que uma determinada classe desempenha o papel de um controlador. o@RequestMapping a anotação é usada para mapear um URL para uma classe inteira ou um método de manipulador específico.

@Controller
@RequestMapping("/hello")
public class HelloController { 
   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }
}

o @Controllera anotação define a classe como um controlador Spring MVC. Aqui, o primeiro uso de@RequestMapping indica que todos os métodos de tratamento neste controlador são relativos ao /hellocaminho. Próxima anotação@RequestMapping(method = RequestMethod.GET)é usado para declarar o métodoprintHello () como o método de serviço padrão do controlador para lidar com a solicitação HTTP GET. Você pode definir outro método para lidar com qualquer solicitação POST no mesmo URL.

Você pode escrever o controlador acima em outro formulário onde você pode adicionar atributos adicionais em @RequestMapping da seguinte maneira -

@Controller
public class HelloController {
   @RequestMapping(value = "/hello", method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }
}

o value atributo indica a URL para a qual o método do manipulador é mapeado e o methodatributo define o método de serviço para lidar com a solicitação HTTP GET. Os seguintes pontos importantes devem ser observados sobre o controlador definido acima -

  • Você definirá a lógica de negócios necessária dentro de um método de serviço. Você pode chamar outro método dentro deste método de acordo com o requisito.

  • Com base na lógica de negócios definida, você criará um modelo dentro deste método. Você pode usar diferentes atributos do modelo setter e esses atributos serão acessados ​​pela vista para apresentar o resultado final. Este exemplo cria um modelo com seu atributo "mensagem".

  • Um método de serviço definido pode retornar um String, que contém o nome do viewa ser usado para renderizar o modelo. Este exemplo retorna "hello" como nome de visão lógica.

Criação de visualizações JSP

Spring MVC oferece suporte a muitos tipos de visualizações para diferentes tecnologias de apresentação. Isso inclui - JSPs, HTML, PDF, planilhas do Excel, XML, modelos Velocity, feeds XSLT, JSON, Atom e RSS, JasperReports, etc. Mas, mais comumente, usamos modelos JSP escritos com JSTL.

Vamos escrever um simples hello visualizar em /WEB-INF/hello/hello.jsp -

<html>
   <head>
      <title>Hello Spring MVC</title>
   </head>
   
   <body>
      <h2>${message}</h2>
   </body>
</html>

Aqui ${message}é o atributo que configuramos dentro do Controlador. Você pode ter vários atributos a serem exibidos dentro de sua visualização.

Exemplos de framework Spring Web MVC

Com base nos conceitos acima, vamos verificar alguns exemplos importantes que o ajudarão a construir seus aplicativos da Web Spring -

Sr. Não. Exemplo e descrição
1 Exemplo Hello World do Spring MVC

Este exemplo explicará como escrever um aplicativo Spring Web Hello World simples.

2 Exemplo de manipulação de formulário Spring MVC

Este exemplo explicará como escrever um aplicativo Spring Web usando formulários HTML para enviar os dados ao controlador e exibir um resultado processado.

3 Exemplo de redirecionamento de página Spring

Aprenda a usar a funcionalidade de redirecionamento de página no Spring MVC Framework.

4 Exemplo de Spring Static Pages

Aprenda como acessar páginas estáticas junto com páginas dinâmicas no Spring MVC Framework.

5 Exemplo de manipulação de exceção de primavera

Aprenda como lidar com exceções no Spring MVC Framework.

Esta é uma funcionalidade Log4J muito fácil de usar dentro de aplicativos Spring. O exemplo a seguir o conduzirá por etapas simples para explicar a integração simples entre Log4J e Spring.

Presumimos que você já tenha log4Jinstalado em sua máquina. Se você não tiver, você pode baixá-lo emhttps://logging.apache.org/e simplesmente extraia o arquivo compactado em qualquer pasta. Vamos usar apenaslog4j-x.y.z.jar em nosso projeto.

Em seguida, vamos ter um Eclipse IDE funcionando e realizar as seguintes etapas para desenvolver um aplicativo da Web baseado em formulário dinâmico usando Spring Web Framework -

Passos Descrição
1 Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado.
2 Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World .
3 Adicione a biblioteca log4j log4j-xyzjar também em seu projeto usando Adicionar JARs externos .
4 Crie classes Java HelloWorld e MainApp no pacote com.tutorialspoint .
5 Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta.
6 Crie o arquivo de configuração log4J log4j.properties sob osrc pasta.
7 A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo.

Aqui está o conteúdo de HelloWorld.java Arquivo

package com.tutorialspoint;

public class HelloWorld {
   private String message;
   
   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage() {
      System.out.println("Your Message : " + message);
   }
}

A seguir está o conteúdo do segundo arquivo MainApp.java

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.log4j.Logger;

public class MainApp {
   static Logger log = Logger.getLogger(MainApp.class.getName());
   
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      log.info("Going to create HelloWord Obj");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      
      log.info("Exiting the program");
   }
}

Você pode gerar debug e errormensagem de forma semelhante à que geramos mensagens de informação. Agora vamos ver o conteúdo deBeans.xml Arquivo

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

</beans>

A seguir está o conteúdo de log4j.properties que define as regras padrão necessárias para Log4J produzir mensagens de log

# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE

# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
# Set the name of the file
log4j.appender.FILE.File=C:\\log.out

# Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true

# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug

# Set the append to false, overwrite
log4j.appender.FILE.Append=false

# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

Quando terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se tudo estiver bem com seu aplicativo, isso imprimirá a seguinte mensagem no console do Eclipse -

Your Message : Hello World!

Se você verificar sua unidade C: \\, deverá encontrar seu arquivo de log log.out com várias mensagens de registro, como a seguir -

<!-- initialization log messages -->

Going to create HelloWord Obj
Returning cached instance of singleton bean 'helloWorld'
Exiting the program

API Jakarta Commons Logging (JCL)

Alternativamente, você pode usar Jakarta Commons Logging (JCL)API para gerar um log em seu aplicativo Spring. JCL pode ser baixado dohttps://jakarta.apache.org/commons/logging/. O único arquivo que tecnicamente precisamos deste pacote é o arquivo commons-logging-xyzjar , que precisa ser colocado em seu classpath de uma forma semelhante à que você colocou log4j-xyzjar no exemplo acima.

Para usar a funcionalidade de registro, você precisa de um objeto org.apache.commons.logging.Log e, em seguida, pode chamar um dos seguintes métodos de acordo com sua necessidade -

  • fatal (mensagem de objeto)
  • erro (mensagem de objeto)
  • advertir (mensagem de objeto)
  • info (mensagem de objeto)
  • depurar (mensagem de objeto)
  • trace (mensagem de objeto)

A seguir está a substituição de MainApp.java, que faz uso da API JCL

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging. Log;
import org.apache.commons.logging. LogFactory;

public class MainApp {
   static Log log = LogFactory.getLog(MainApp.class.getName());

   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      log.info("Going to create HelloWord Obj");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();

      log.info("Exiting the program");
   }
}

Você deve se certificar de que incluiu o arquivo commons-logging-xyzjar em seu projeto, antes de compilar e executar o programa.

Agora, mantendo o resto da configuração e do conteúdo inalterado no exemplo acima, se você compilar e executar seu aplicativo, obterá um resultado semelhante ao obtido usando a API Log4J.