Annotations com Spring 2.5 + Thinlet
O Spring Framework a partir de sua versão 2.5 introduziu uma quantidade considerável de annotations a disposição do desenvolvedor. Ainda é possível usar a configuração clássica em XML, mas agora além dos recursos de anotações é possível mesclar os dois no mesmo código.
Vou demonstrar através de um exemplo simples utilizando como GUI o Thinlet. O Thinlet é uma biblioteca que permite a criação de GUI através de definição em XML da interface, como se fosse um XUL, o que dá muita flexibilidade. O projeto de GUI está meio parado, acho que o ultimo release foi em 2005, mas mesmo assim, é uma biblioteca simples de se usar e principalmente muito leve.
Foi utilizado o Spring Framework 2.5 mas pode ser usado qualquer versão do mesmo sendo 2.5.x. Vamos ver como utilizar algumas anotações que o Spring introduziu aos seus usuários. Também vou abordar como integrar o uso dessas anotações com o desenvolvimento em XML clássico.
Dependências:
A Definição da GUI via o Thinlet segue a baixo. Você deve chamar esse arquivo de
Calculator.XML.
Eu criei o Enumeration Operation para a representação das operações da calculadora. Segue o código a baixo.
Para realizar as operações matemáticas eu criei um Service e chamei de CalculatorService. Segue a baixo.
Esse Service possui o método calculate que recebe dois Double como parâmetros mais uma objeto do tipo Operation que é a operação que deve ser efetuada, a partir da instância do objeto de Operation o serviço decide qual operação deve ser efetuada.
@Component: Aqui que começa a brincadeira. Com essa anotações estamos dizendo para o Spring que essa classe é um componente, logo se a mesma for scaneada ela irá para a BeanFactory do Spring. Isso é o mesmo que fazer a declaração do Bean no xml informando id e class. Por default o id do bean será o nome da classe, mas essa informação pode ser modificada.
Agora vamos a tela. Classe Calculator
@Component(value="calc"): Com isso estamos declarando que a classe Calculator é um componente no Spring, ou seja, um bean no contexto do Spring. Com o parametro value estou disendo que o identificador desse componente é "calc" que é na verdade o id do bean.
@Autowired private CalculatorService cs;: Com essa anotação estou fazendo uma injeção de dependências, como eu usei !Autoeired o spring ira aplicar auto-wire by type, nesse exemplo não exite problema pois estou lidando direto com a classe concreta porem cuidado com esse recurso ele pode dar muitas dores de cabeça se for usado impropriamente.
Para rodar a aplicação crie a classe MainApp. Segue a baixo.
Nessa classe o contexto do Spring é subido. E um bean é recuperado do contexto. Você ira entender mais sobre o que está aconetcendo no proximo tópico que é o contexto do spring.
spring-beans.xml
Esse é o clássico xml de beans do Spring. Vocês podem notar de novo os nodos:
<context:annotation-config/>
<context:spring-configured/>
<context:component-scan base-package="com.blogspot.diegopacheco" annotation-config="true" />
Esses são os nodos necessários para o uso de anotações no Spring. Um recurso muito legal que o Spring introduziu é o context:compoment-scan com esse recurso o spring passa um scanner no seu class-path a procura de beans. Adivinhe que beans ele ira adicionar ao contexto? Ele irá adicionar o que contem a acontação @Component.
No final é definido o bean thinlet.FrameLauncher que é um utilitário do Thinlet para iniciar as aplicações. Ele foi definido como um bean normal do Spring, porem foi feito via constructor injection a injeção do bean "calc" que na verdade ira ser carregado pela scanner do Spring. Dessa forma conseguimos injetar beans oriundos de XML ou anotações, no spring 2.5 isso tudo é transparente.
Ainda existem muitos recursos no Spring 2.5 em relação a anotações. Vale a pena conferir. Mas por hoje é só. :)
Vou demonstrar através de um exemplo simples utilizando como GUI o Thinlet. O Thinlet é uma biblioteca que permite a criação de GUI através de definição em XML da interface, como se fosse um XUL, o que dá muita flexibilidade. O projeto de GUI está meio parado, acho que o ultimo release foi em 2005, mas mesmo assim, é uma biblioteca simples de se usar e principalmente muito leve.
Foi utilizado o Spring Framework 2.5 mas pode ser usado qualquer versão do mesmo sendo 2.5.x. Vamos ver como utilizar algumas anotações que o Spring introduziu aos seus usuários. Também vou abordar como integrar o uso dessas anotações com o desenvolvimento em XML clássico.
Dependências:
- spring framework 2.5.x
- commons-logging
- spring-aspects
- aspectjrt
- thinlet
A Definição da GUI via o Thinlet segue a baixo. Você deve chamar esse arquivo de
Calculator.XML.
Eu criei o Enumeration Operation para a representação das operações da calculadora. Segue o código a baixo.
package com.blogspot.diegopacheco.thinletspring25;
/**
* Enum que define as operações matematicas.
*
* @author Diego Pacheco
* @version 1.0
*/
public enum Operation {
SOMA {
return 0;
}
},
SUBTRACAO {
public int getValue() {
return 1;
}
},
DIVISAO {
public int getValue() {
return 2;
}
},
MULTIPLICACAO {
public int getValue() {
return 3;
}
};
public int getValue() {
return -1;
}
}
Para realizar as operações matemáticas eu criei um Service e chamei de CalculatorService. Segue a baixo.
pre
package com.blogspot.diegopacheco.thinletspring25;
import org.springframework.stereotype.Component;
/**
* Classe de Serviço da Calculadora
*
* @author Diego Pacheco
* @version 1.0
*/
@Component
public class CalculatorService {
public Double calculate(Double v1, Double v2, Operation op) {
Double result = 0d;
switch (op.getValue()) {
case 0:
result = v1 + v2;
break;
case 1:
result = v1 - v2;
break;
case 2:
result = v1 / v2;
break;
case 3:
result = v1 * v2;
break;
default:
throw new RuntimeException("A operacao[" + op
+ "] não é suportada pelo service.");
}
return result;
}
}
Esse Service possui o método calculate que recebe dois Double como parâmetros mais uma objeto do tipo Operation que é a operação que deve ser efetuada, a partir da instância do objeto de Operation o serviço decide qual operação deve ser efetuada.
@Component: Aqui que começa a brincadeira. Com essa anotações estamos dizendo para o Spring que essa classe é um componente, logo se a mesma for scaneada ela irá para a BeanFactory do Spring. Isso é o mesmo que fazer a declaração do Bean no xml informando id e class. Por default o id do bean será o nome da classe, mas essa informação pode ser modificada.
Agora vamos a tela. Classe Calculator
package com.blogspot.diegopacheco.thinletspring25;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import thinlet.Thinlet;
/**
* Esse é um gui definido atres do Thinlet.
* @author Diego Pacheco
* @version 1.0
*/
@Component(value="calc")
public class Calculator extends Thinlet {
private static final long serialVersionUID = 1L;
@Autowired
private CalculatorService cs;
public Calculator() throws Exception {
add(parse(Calculator.class.getSimpleName() + ".xml"));
}
public void calculate(String number1, String number2, String operation, Object result) {
try {
Double v1 = Double.parseDouble(number1);
Double v2 = Double.parseDouble(number2);
Operation op = null;
if("+".equals(operation)){
op = Operation.SOMA;
}else if("-".equals(operation)){
op = Operation.SUBTRACAO;
}else if("/".equals(operation)){
op = Operation.DIVISAO;
}else if("*".equals(operation)){
op = Operation.MULTIPLICACAO;
}
setString(result, "text", String.valueOf(cs.calculate(v1, v2,op)));
} catch (NumberFormatException nfe) {
getToolkit().beep();
}
}
public CalculatorService getCs() {
return cs;
}
public void setCs(CalculatorService cs) {
this.cs = cs;
}
}
@Component(value="calc"): Com isso estamos declarando que a classe Calculator é um componente no Spring, ou seja, um bean no contexto do Spring. Com o parametro value estou disendo que o identificador desse componente é "calc" que é na verdade o id do bean.
@Autowired private CalculatorService cs;: Com essa anotação estou fazendo uma injeção de dependências, como eu usei !Autoeired o spring ira aplicar auto-wire by type, nesse exemplo não exite problema pois estou lidando direto com a classe concreta porem cuidado com esse recurso ele pode dar muitas dores de cabeça se for usado impropriamente.
Para rodar a aplicação crie a classe MainApp. Segue a baixo.
package com.blogspot.diegopacheco.thinletspring25;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Classe de entrada para aplicação.
* @author Diego Pacheco
* @version 1.0
*/
public class MainApp {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-beans.xml");
ac.getBean("frameLauncherPrincipal");
}
}
Nessa classe o contexto do Spring é subido. E um bean é recuperado do contexto. Você ira entender mais sobre o que está aconetcendo no proximo tópico que é o contexto do spring.
spring-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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-autowire="no" default-dependency-check="none" default-lazy-init="true" > <context:annotation-config/> <context:spring-configured/> <context:component-scan base-package="com.blogspot.diegopacheco" annotation-config="true" /> <bean id="frameLauncherPrincipal" class="thinlet.FrameLauncher" lazy-init="true" > <constructor-arg index="0" value="Calculatora Simples" /> <constructor-arg index="1"> <ref bean="calc" /> </constructor-arg> <constructor-arg index="2" value="300" /> <constructor-arg index="3" value="80" /> </bean> </beans>
Esse é o clássico xml de beans do Spring. Vocês podem notar de novo os nodos:
<context:annotation-config/>
<context:spring-configured/>
<context:component-scan base-package="com.blogspot.diegopacheco" annotation-config="true" />
Esses são os nodos necessários para o uso de anotações no Spring. Um recurso muito legal que o Spring introduziu é o context:compoment-scan com esse recurso o spring passa um scanner no seu class-path a procura de beans. Adivinhe que beans ele ira adicionar ao contexto? Ele irá adicionar o que contem a acontação @Component.
No final é definido o bean thinlet.FrameLauncher que é um utilitário do Thinlet para iniciar as aplicações. Ele foi definido como um bean normal do Spring, porem foi feito via constructor injection a injeção do bean "calc" que na verdade ira ser carregado pela scanner do Spring. Dessa forma conseguimos injetar beans oriundos de XML ou anotações, no spring 2.5 isso tudo é transparente.
Ainda existem muitos recursos no Spring 2.5 em relação a anotações. Vale a pena conferir. Mas por hoje é só. :)