Série Spring: JEE:CRUD Hibernate com Spring 3 + JSF 2.0

 

Olá Pessoal,

Continuando a nossa série de post sobre o Spring vamos, ver hoje como fazer um simples CRUD com Spring + Hibernate + JSF.O objetivo maior, é para quem está chegando possa ver como juntar as tecnologias de maneira simples. E o melhor de tudo veremos como Spring  é uma mão na roda de verdade.

Lets go…

Starting…

A nossa aplicação será super simples, vamos fazer o cadastramento de carros, e exercitar o CRUD. Para exibição e cadastro dos veículos, vamos fazer uma página JSF de maneira mais simples possível e que seja funcional.  A seguir os requisitos:

Requisitos:

  • – MysqlSQL 5.x
  • – Hibernate 3.x
  • – Spring 3.x
  • – Tomcat 7.x
  • – JSF 2.x
  • – Jboss tools

Vou considerar que você vem acompanhando a série de posts  Spring no blog e alguns pontos que já foi tratado aqui, não estarei explicando novamente, dúvidas? Farei um link para o post referente. E sobre JSF 2.x também irei considerar que vc já brincou com o framework, mesmo que seja na versão anterior. Estou ressaltando isso, para que não entre no detalhes de cada ponto, e que o post fique mais direto e mão na massa.

 Configuração

Primeiro ponto é , criar um projeto JSF Project (é preciso ter o jboss tools instalado).

projetocrudspringcar

Escolha a opção JSF 2 na tela do assistente.  Em seguida crie os packages conforme a seguir, por enquanto eles estarão vazios, mas iremos daqui a pouco colocar carne no esqueleto : ).

Adicione os .jars na pasta lib do projeto:

webinflib

Criando o source unit/test

Observe que eu criei um source para os unit tests:

unitestscarcrud

Agora vamos criar o arquivo de configuração do Spring. Na verdade teremos dois, um para os unit tests e outro para aplicação. Apenas dupliquei, mas poderíamos otimizar o de unit tests importando apenas o que precisamos a partir do arquivo principal, mas não quis fazer isso por agora, vamos focar no CRUD.

Crie um arquivo springconfiguration.xml  dentro de WEB-INF, o nome poderia ser qualquer um, normalmente utiliza-se applicaiton-context.xml, mas quis fazer diferente para que você veja que o nome não importa.

Não irei adicionar o cabeçalho apenas o código, que não tem nada de diferente do que já vimos nos posts quando vimos hibernate com Spring.

<context:component-scan base-package=“*”/>

<tx:annotation-driven/> 

<tx:advice id=“txAdvice”>

<tx:attributes>

<tx:method name=“add*” propagation=“REQUIRED”/>

<tx:method name=“delete*” propagation=“REQUIRED”/>

<tx:method name=“read*” propagation=“REQUIRED”/>

<tx:method name=“*” propagation=“SUPPORTS” read-only=“true”/>

</tx:attributes>

</tx:advice> 

<aop:config>

<aop:advisor pointcut = “execution(* *..CarDAO.*(..)))” advice-ref=“txAdvice”/>

</aop:config> 

<bean class=“org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor”/> 

<bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>

<property name=“driverClassName” value=“com.mysql.jdbc.Driver”/>

<property name=“url” value=“jdbc:mysql://localhost/test”/>

<property name=“username” value=“root”/>

<property name=“password” value=“camilo2593”/>

</bean> 

<bean id=“sessionFactory” class=“org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>

<property name=“dataSource” ref=“dataSource”/>

<property name=“packagesToScan” value=“br.com.camilolopes.car.domain.bean”/>

<property name=“hibernateProperties”>

<props>

<prop key=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</prop>

<prop key=“hibernate.hbm2ddl.auto”>update</prop>

</props>

</property>

</bean>

<bean id=“transactionManager” class=“org.springframework.orm.hibernate3.HibernateTransactionManager”>

<property name=“sessionFactory” ref=“sessionFactory”/>

</bean>

 

Agora precisamos fazer umas configurações no arquivo web.xml

<!– dizendo onde está meu arquivo de configuração –>

 <context-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>/WEB-INF/springconfiguration.xml,</param-value>

 </context-param>

 <!– configurando o context loader do Spring, esse cara permite carregar N arquivos de configuração –>

 <listener>

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

 </listener>

 <!– esse cara permite dizer ao JSF que os beans serão gerenciados pelo Spring é requerido ter essa

 configuração –>

 <listener>

  <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>

 </listener>

 Testando.

Se você subir aplicação agora, não há nade especial, apenas vai subir o exemplo que temos no JSF Project que é criado pelo Jboss tols. Mas, é bom testar para garantir que as mudanças que fizemos no web.xml , não afetou nada da aplicação.

Arquivo de configuração do spring para unit tests

Agora vamos criar um arquivo de configuração para executar os unit tests. Mas, pq? Simplesmente pq a partir de uma classe de teste você não consegue ler um arquivo que está em web-inf, então você precisa ter o arquivo em source.

Noticia boa: o código é o mesmo que  do arquivo anterior, então duplique o XML apenas, o meu chamei de springconfiguration-test.xml e coloquei no JavaSource:

sourcespringconfiuration-test

Agora vamos começar a brincadeira, ou seja, desenvolver.

Development

Começaremos pelos testes claro. Para isso criaremos uma classe que testará o serviço que implicitamente testa as classes DAO.

Antes criaremos os testes precisamos entender que é importante entender que:

– após testes terem sido executados este deve dar rollback, para que os dados não fiquem no banco;

– os testes não podem ser dependentes de outro test, ou seja, um @Test não pode depender da execução de outro @Test

Por enquanto, ao criar os unit test é esperado que nem compile, já que não temos nenhuma classe pronto, mas é isso que queremos, que os testes nos ensinem a  desenvolver as regras de negocio que precisamos.

O primeiro teste vai nos permitir  testar o salvarOrUpdate  da nossa aplicação, poderia ter separado em dois testes um para save e outro para update, mas não quis entrar muito detalhes sobre testes aqui, senão o post ia fica 2x maior e sinceramente não curto muito posts grandes.

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations={“classpath:springconfiguration-test.xml”})

@TransactionConfiguration(transactionManager=”transactionManager”,defaultRollback=true)

@Transactional

public class CarServiceImplTest {

      @Autowired

      private CarServices carServices;

      private Car car;

      @Before

      public void setUp() throws Exception {

      car = new Car();

      car.setDescription(“ferrari”);

      car.setPriceSale(BigDecimal.ZERO);

      car.setYear(“2010”);

      }

      @Test

      public void testSaveOrUpdate() {

            try{

                  carServices.saveOrUpdate(car);

            }catch (Exception e) {

                  fail(“not expected result”);

            }

      }

 

Observe que configuramos o rollback igual a true para tudo, então sempre será feito rollback e nada é inserido no banco. Mas,se você quer inserir no banco para um método especifico, basta anotarmos  no método assim: @Rollback(false) //isso faz inserir no banco 

Note: nesse exemplo não estou usando um banco em memória, então  é preciso que o Mysql esteja rodando para que os testes possam ser executados, o ideal é era fazer os testes rodarem em um banco em memória assim, não teríamos essa dependência, pois o banco seria iniciado sempre que os testes fossem executados.

Agora vamos criar as classes que o Eclipse está reclamando, vamos começar pela entidade Car:

@Entity(name=”SALE_CARS”)

public class Car implements Serializable{

      private static final long serialVersionUID = 2792374994901518817L;

      @Id

      @GeneratedValue

      private Long id;

      private String description;

      private BigDecimal priceSale;

      private String year;

//getters/setters omitidos

 

Services

Vamos criar os serviços, mas antes precisamos ter uma interface para os nossos serviços CRUD então:

public interface CarServices {

      void saveOrUpdate(Car car);

      void delete(Car car);

      List<Car> listAll();

}

 Agora vamos criar a classe em si:

@Service

public class CarServiceImpl implements CarServices {

      @Autowired

      private CarDAO carDAO;     

      public void saveOrUpdate(Car car) {

            carDAO.addCar(car);

      }

//setters CarDAO omitido. Não é preciso criar get.

DAO Interface

Também criaremos uma interface para o DAO e em seguida a implementação do método save

public interface CarDAO {

      void addCar(Car car);

      List<Car> readAll();

      void deleteCar(Long id);     

}

@Repository

public class CarDAOImpl implements CarDAO {

      @Autowired

      private SessionFactory sessionFactory;

           private Session getCurrentSession(){

            return sessionFactory.getCurrentSession();

      }

      public void addCar(Car car) {

            getCurrentSession().saveOrUpdate(car);

      }

//setters sessionFactory ommitido, não é preciso cria get.

Claro que os demais métodos da interface estarão sem código por enquanto, pois o objetivo agora é testar o create do CRUD.

Testando via Unit Tests

Agora vamos rodar o nosso teste e ver o resultado, se você não adicionou o JUNIT4 ao seu projeto, o Eclipse vai fazer a sugestão.

Note: Ao rodar o unit tests e você ter a exceção:

org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available

faça o download http://cglib.sourceforge.net/ e adicione a lib ao seu projeto na pasta web-inf/lib

O resultado

saveorupdategreen

Agora precisamos desenvolver o RUD.  A seguir os testes que foram criados e depois, o código com a resolução:

 @Test

public void testDelete() {

            try{carServices.saveOrUpdate(car);

                  carServices.delete(car);

            }catch (Exception e) {

String notExpectedResult = “Not expected result “+ e.getMessage();

                  fail(notExpectedResult);

            }

      }

      @Test

      public void testListAll() {

            carServices.saveOrUpdate(car);

            assertFalse(carServices.listAll().isEmpty());

      }

 Classe DAO

public List<Car> readAll() {

            return getCurrentSession().createCriteria(Car.class).list();

      } 

      public void deleteCar(Long id) {

            Criteria criteria = getCurrentSession().createCriteria(Car.class);

            criteria.add(Restrictions.eq(“id”, id));

            Car car = (Car) criteria.uniqueResult();

            getCurrentSession().delete(car);

      }

 Classe de Serviço:

      public void delete(Car car) {

            carDAO.deleteCar(car.getId());

      } 

      public List<Car> listAll() {     

            return carDAO.readAll();

      } 

      public void setCarDAO(CarDAO carDAO) {

            this.carDAO = carDAO;

      }

Rodando todos os testes:

reusultadoAlltestescrud

Há um detalhe que fiz de propósito, observe que não tem um teste para validar o update, deixarei esse como motivação para você brincar mais com unit test  : ).

 

resultdbcrudspringunittests

Observe que nosso banco está vazio, ou seja, nada foi adicionado.

JSF

Agora que já sabemos que o nosso CRUD está funcionando, vamos trazer isso para o nosso front-end com JSF.:

Crie uma classe controller

@Controller

public class CarController {

      @Autowired

      private CarServices carServices;

      private Car car;     

      private List<Car> listCars;     

      public CarController() {

            car = new Car();

      }     

      public void save(){

            carServices.saveOrUpdate(car);

            car = new Car();

      } 

      public void delete(){

            carServices.delete(car);

            car = new Car();

      }     

      public List<Car> getListCars() {

            listCars = carServices.listAll();

            return listCars;

      }

                //setters/getters omitidos

Observe que nosso controller conecta com o nosso service. Só isso que precisamos. Se você já brinca com JSF nada de especial por aqui.

Criando  .xhtml

Na verdade vamos alterar o index.xhtml que foi criado por default pelo jboss tools:

<html><head><meta http-equiv=“Refresh” content=“0; URL=pages/sales-car.jsf”/></head></html>

 

Apenas fizemos um redirecionamento para uma página que vamos criar.

sales-car.xhtml

Crie um xhtml, com suporte facelets e adicione o código a seguir:

<body>

<h:form>

<h:commandLink action=“form-car” value=“::Cadastro”/>

</h:form>

</body>

 

Essa página vai levar para a tela de cadastro:

form-car.xhtml

Vamos por parte:

Primeiro temos o código do form:

<h:form>

<h:panelGrid columns=“2”>

<h:outputLabel value=“Car Description: “/>

<h:inputText value=“#{carController.car.description}”/>

<h:outputLabel value=“Sale Price: “/>

<h:inputText value=“#{carController.car.priceSale}” converter=“javax.faces.BigDecimal”/>

<h:outputLabel value=“year:”/>

<h:inputText value=“#{carController.car.year}”/>

<h:commandButton value=“Save” actionListener=“#{carController.save}”/>

</h:panelGrid>

Agora vamos ter o código de uma tabela que exibi o usuário adicionado e permite editar/deletar :

<h:dataTable id=“cartable” value=“#{carController.listCars}” var=“car” cellpadding=“10”>

<h:column>

<f:facet name=“header”>

<h:outputText value=“Id”/>

</f:facet>

#{car.id}

</h:column>

<h:column>

<f:facet name=“header”>

<h:outputText value=“Description”/>

</f:facet>

#{car.description}

</h:column>

<h:column>

<f:facet name=“header”>

<h:outputText value=“Sale Price”/>

</f:facet>

<h:outputText value=“#{car.priceSale}”>

<f:convertNumber type=“currency” maxFractionDigits=“3”/>

</h:outputText>

</h:column> 

<h:column>

<f:facet name=“header”>

<h:outputText value=“Year”/>

</f:facet>

#{car.year}

</h:column> 

<h:column>

<f:facet name=“header”>

<h:outputText value=“Action”/>

</f:facet>

<h:commandLink value=“Delete” action=“#{carController.delete}”>

<f:setPropertyActionListener target=“#{carController.car}” value=“#{car}”/>

</h:commandLink>

<h:commandLink value=” | Edit “>

<f:setPropertyActionListener target=“#{carController.car}”  value=“#{car}”/>

</h:commandLink>

</h:column> 

</h:dataTable>

</h:form>

 

Pronto. Esse é o nosso front-end para testarmos o CRUD, vamos subir aplicação, clique com o botão direito  no projeto e escolha  Run as >> Run on Server

Note: Caso não tenha um servidor selecionado com o projeto o Eclipse vai solicitar que escolha um, no meu caso escolhi o tomcat e informei o local de instalação. Se der tudo certo você terá a tela a seguir:

screenaddjsfcars

Vamos para tela de cadastro clicando no botão “Cadastro”

 

cadcarscreenspring

addingcar

 

carsresultscreen

Verificando no bd:

 

checkingbdcars

Editando:

 

carrdseditjsf

Resultado Edição:

editresultjsfspring

E no banco:

 

editbdcars

 

Ufa! Post longo heim, e olha que reduzir. Mas, vou ficando por aqui. E espero que tenham gostado.

Abraços, see ya!!!

Série Spring: Aplicação JEE com JSF 2.0 + Spring 3.0

 

Olá Pessoal,

No post de hoje veremos como usar Spring em nossas aplicações JEE tendo o JSF no nosso front-end. Vou considerar que você já conhece o básico e configuração de cada um dos frameworks, mas na hora de fazer a integração, veio aquela pergunta: “E agora como faço?”.

Lets go… 

Starting…

Primeiramente precisamos ter nosso ambiente de desenvolvimento pronto, para isso  você precisa ter os .jars do JSF 2.x e do Spring core 3.x.  No nosso exemplo estou usando a versão do Spring 3.2 e o JSF 2.0.9 e como IDE optei pelo STS Tools. O motivo que ele  vem com vários plugins já por default  e é uma mão  na roda.

Nossos .jars:

  • – JSF 2.X
  • – Spring 3.x
  • -commons-logging-1.1.1.jar

Note: como Servidor app estou usando o Tomcat 7.0

Garanta que você já tem tudo isso antes de começar a desenvolver.

Desenvolvimento

Agora vamos meter mão na massa. Primeiro crie um Spring template Project  na lista de opções escolha Spring Hibernate Utility Apesar que não vamos usar nada de Hibernate, o template já vem com a estrutura do projeto para web e precisamos apenas dar uns tapas para ficar como queremos, para isso o projeto vai está “quebrando” ou seja, com uma exclamação:

helloSpringJSFProject

Note: se vc já tem um projeto JEE, só vai precisar adicionar suporte ao Spring.

Note 2: você também poderia criar um JSF Project e adicionar o Spring, enfim há N possibilidades.

Vamos deletar os arquivos que veio no template que não precisamos:

hellospringjsfdelete

Agora vamos adicionar suporte ao JSF para o projeto. Basta clicar com o botão direito do mouse no projeto e escolher:

 

configurejsfhellospringproject

Na tela a seguir bastar dar ok:

jsfscreenspringhello

Adicione os .jars na pasta lib:

 

jarslibhellopspring

Crie os packages a seguir:

hellospringpackages

A nossa aplicação será bem simples, daremos um Hello para um determinado usuário que será criado quando o método getUserInformation é invocado pelo controller.

User.java

public class User {

    private String name;

    private String lastName;

    private Integer age; 

//getters/setters  omitidos

}

Criaremos uma interface para o serviço

UserService.java

public interface UserService {

    public User getUserDetails();

}

 Agora temos a implementação da interface:

@Service

public class UserServiceImpl implements UserService {

     private User user;   

    public UserServiceImpl() {

     user = new User();

     user.setName(“camilo”);

     user.setLastName(“lopes”);

     user.setAge(10);

    }

    @Override

    public User getUserDetails() {       

        return user;

    } 

}

 Antes de criarmos a classe de controller precisamos fazer umas configurações no arquivo web.xml e também criarmos o nosso arquivo de configuração do Spring. Primeiro vamos alterar o web.xml

Adicione o cara que carrega as configurações do Spring

<listener>

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

 </listener>

 

Vamos dizer para ele onde pegar as configurações do Spring:

<context-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>/WEB-INF/springconfiguration.xml</param-value>

 </context-param>

 Apesar que não criamos  o arquivo springconfiguration.xml , mas não há problemas algum.

E agora vamos colocar o cara que permitirá utilizar os escopos padrões de uma aplicação web

<listener>

  <listener-class>org.springframework.web.context.request.RequestContextListener

</listener-class>

 </listener>

 E assim terminamos a configuração do web.xml

Face-config.xml

E agora vamos dizer ao JSF para delegar a criação do ManagedBeans para o Spring, mas para isso vamos alterar o arquivo face-config.xml

<face-config>

<application>

  <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>

 </application>

</faces-config>

Criando o  arquivo de configuração do Spring

Aqui chamei meu arquivo de configuração do Spring de springconfiguration.xml e como vimos anteriormente informamos ele no web.xml para que ao iniciar aplicação o application context saiba onde e quem buscar.

hellpspringconfigurationfile

Portanto crie um arquivo .xml conforme a seguir:

<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:component-scan base-package=“*”/> 

</beans>

 

Só isso que precisamos. 

Criando a classe controller

UserController.java

@Controller

@Scope(“request”)

public class UserController {

    @Autowired

    private UserService userServ; 

    public User getUserInformation(){       

        return userServ.getUserDetails();

    }

    public void setUserServ(final UserService userServ) {

        this.userServ = userServ;

    }

}

Se você já conhece o Spring nada de especial aqui, apenas trocamos as anotações do JSF pela dos Spring.

Criando a página .xhtml

Vamos criar uma página home.xhtml que terá o código JSF. Para isso crie uma .xhtml withou facets.

E no body da página adiicone:

Hello <h:outputText value=“#{userController.userInformation.name}” />

 Agora clique com o botão direito do mouse no projeto e escolha Run On Server e o resultado será:

<img hellospringresultado>

Acessando http://localhost:8080/nomedoprojet/home.jsf

Note: lembrando que para dar suporte .jsf você precisa dizer isso no web.xml, assim:

<servlet-mapping>

  <servlet-name>Faces Servlet</servlet-name>

  <url-pattern>*.jsf</url-pattern>

 </servlet-mapping>

 

Pronto. Agora temos o nosso projeto JEE integrado com o Spring e tirar todo o beneficio que o framework nos traz. Simples não?

Abraços, 

Série Spring: Transaction via Annotation Spring 3 + Hibernate

Olá Pessoal,

No post de hoje veremos como usar Annotations nas nossas transaction. Para isso teremos como exemplo uma aplicação bem simples para irmos direto ao ponto.

Lets go…

 Starting…

Primeiro ponto é iniciarmos pelo arquivo de configuração do Spring. Antes disso,  vou assumir que você tem os .jars necessário: mysql 5, hibernate 3.x, spring 3.x, aop, aspectJ.

Esse é o projeto:

springannotationtransactionproject

Configurando o Spring

A seguir segue a configuração do Spring, aproveitei e coloquei o comentário in line para facilitar o entendimento:

Cabeçalho

<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”

xmlns:tx=“http://www.springframework.org/schema/tx”

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

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd”>

 

E o restante:

<context:component-scan base-package=“*”/>

<!– declarando a transation por default busca pelo id transactionManager –>

<tx:annotation-driven/> 

<!– faz o translate das exception para Spring Exception –>

<bean class=“org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor”/> 

<bean id=“transactionManager” class=“org.springframework.orm.hibernate3.HibernateTransactionManager”>

<property name=“sessionFactory” ref=“sessionFactory”/>

</bean>

 

<!– criando meu datasource –>

<bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>

<property name=“driverClassName” value=“com.mysql.jdbc.Driver”/>

<property name=“url” value=“jdbc:mysql://localhost/test”/>

<property name=“username” value=“root”/>

<property name=“password” value=“camilo2593”/>

</bean> 

<!– configurando o sessionFactory  –>

<bean id=“sessionFactory” class=“org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>

<property name=“dataSource” ref=“dataSource”/>

<!– informando o package onde estão os beans annotated –>

<property name=“packagesToScan” value=“br.com.camilolopes.model.bean”/>

<!– aqui o Hibernate properties –>

<property name=“hibernateProperties”>

      <props>

      <prop key=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</prop>

      <prop key=“hibernate.hbm2ddl.auto”>update</prop>

      </props>

</property>

</bean>

</beans>

 

Onde está o segredo?

Exatamente nessa linha:

<!– declarando a transation por default busca pelo id transactionManager –>

<tx:annotation-driven/>

Pronto essa linha habilita reconhecer annotation @Transactional. Que faremos logo a seguir

Desenvolvendo

Vamos meter mão na massa na parte Java:

Entidade

@Entity

public class ProductTech implements Serializable{

      private static final long serialVersionUID = -206121128264026525L;

      @Id

      @GeneratedValue

      private Long id;

      private String nameProduct;

                //getters/setters omitidos

 

Interface DAO

public interface ProductDAO {

      void save(ProductTech product);

}

 

Implementação da Interface 

@Repository

public class ProductDAOImpl implements ProductDAO {

      private SessionFactory sessionFactory;

      @Autowired

      public ProductDAOImpl(SessionFactory sessionFactory) {

            this.sessionFactory = sessionFactory;

      }

      private Session currentSession(){

            return sessionFactory.getCurrentSession();

      } 

      @Override  //para execução deste método é requerido uma transação, é isso que estamos dizendo aqui

      @Transactional(propagation=Propagation.REQUIRED,readOnly=false)

      public void save(ProductTech product) {

            currentSession().save(product);

            System.out.println(“product saved with sucess”);

      }

}

Testando

E para testar vamos fazer dessa vez com uma classe que tem o método main, caso você ainda não esteja tão acostumado com unit test (deveria):

public class MainTestDAO {

      public static void main(String[] args) {

            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“config/springconfiguration.xml”);

            ProductDAO bean = (ProductDAO) applicationContext.getBean(“productDAOImpl”);

            ProductTech product= new ProductTech();

            product.setNameProduct(“tablet samsung galaxy”);

            bean.save(product);

      }

}

Resultado:

springtransactionannotationresult

É isso ia. Simples e fácil usar anotações para transações no Spring.

Abracos! Vou ficando por aqui.

See ya!!!

Série Spring: Spring AOP com annotations

 

Olá Pessoal,

No post de hoje vamos ver como usar annotations   para AOP é bem simples.Já vimos aqui  com XML e agora vamos para o que há de melhor  desde do Java 5 que é o uso de Annotations.

Lets go…

 Starting

O post é bem curto e procurei  ser bem objetivo, então considerando que você já tem seu arquivo de spring configurado  para usar aop, vamos apenas atualizar para habilitar o recurso de annotations  e aproveitei removi os beans  usando auto-discovering do Spring. Vamos começar pela configuração do arquivo springconfiguration.xml (o nome que dei ao meu arquivo de configuração).

Antes disso, crie um projeto novo e dê o nome que quiser.

Note: lembre-se de adicionar os .jars do Spring, AOP e AspectJ ao projeto:

 springaopannotationsproject

Configurando .xml do Spring

<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”

xmlns:aop=“http://www.springframework.org/schema/aop”

xsi:schemaLocation=“http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd”>

 <context:component-scan base-package=“*”/>

<aop:aspectj-autoproxy/>

 </beans>

 

Deixei seu arquivo de configuração assim. A única coisa nova de aop, foi que adicionar a linha <aop:aspectj-autorproxy/>  que nos permite usar annotations.

Criando o bean

A seguir vamos criar o bean , nada demais neles:

@Component

@Scope(value=”prototype”)

public class Student {

      private String name;

//    this is DI via annotations

      @Autowired

      private Course course;

      public String getName() {

            return name;

      }

      public void setName(String name) {

            if (name==null) {

                  throw new IllegalArgumentException();

            }

            this.name = name;

      }

      public Course getCourse() {

            return course;

      }

      public void setCourse(Course course) {

            this.course = course;

      }     

      public void teste(){           

      }

}

O outro bean:

@Component

public class Course {

      private String nameCourse; 

      public String getNameCourse() {

            return nameCourse;

      } 

      public void setNameCourse(String nameCourse) {

            this.nameCourse = nameCourse;

      } 

}

 

Agora vamos criar uma classe que será responsável  por registrar uma mensagem antes;após de determinados métodos, ou seja, as regras do AOP estarão aqui:

@Aspect

@Component

public class Audit {

//    aqui com o metodo especifico

      @Pointcut(“execution(* br.com.camilolopes.bean.Student.setName(..))”)

      public void aopteste(){} 

      @Pointcut(“execution(* br.com.camilolopes.bean.Course.setNameCourse(..))”)

      public void aopcourse(){}     

      @Pointcut(“execution(* *.*test*(..))”)

      public void aopanywhere(){}     

      @AfterReturning(“aopteste()”)

      public void register(){

            System.out.println(“Student registred”);

      }

      @After(“aopcourse()”)

      public void finished(){

            System.out.println(“Course finished”);

      }

      @AfterThrowing(“aopteste()”)

      public void problem(){

            System.out.println(“Happened problem here”);

      }

      @Before(“aopteste()”)

      public void starting(){

            System.out.println(“application is starting…”);

      }

      @AfterReturning(“aopanywhere()”)

      public void anywhere(){

            System.out.println(“anywhere test”);

      }

}

Observe que anotei a classe com @Component para que o Spring saiba que precisa registrar ela no contexto. Caso contrário, nada rola. Agora vamos entender os pointcuts criados:

  • Primeiro: criamos um pointcut que sempre será chamado quando um método especifico for chamado nesse caso o método  setName da classe Student.
  • Segundo: o mesmo que acima, exceto que para a classe Course.
  • Terceiro :  agora criamos um que estou dizendo: “de qualquer lugar da aplicação e qualquer método que comece com test e terminar com qualquer coisa.

E  os métodos a seguir é o que serão chamados  com base no que tipo de anotação que definimos, observe que temos um que será chamado apenas no caso de acontecer uma exceção quando no método setName da classe Student.

Testando

Para testar aplicação criei uma classe de teste

Classe de Test

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations={“classpath:config/springconfiguration.xml”})

public class StudentTest {

      @Autowired

      private Student student;

      @Before

      public void setUp() throws Exception {

      } 

      @Test

      public void testNameCourse() {

            student.getCourse().setNameCourse(“TDD”);

            assertEquals(“TDD”,student.getCourse().getNameCourse());

      }     

      @Test

      public void testNameStudent(){

            student.setName(“Camilo”);

            assertEquals(“Camilo”, student.getName());

            student.teste();

      }

      @Test(expected=IllegalArgumentException.class)

      public void testNameIsNullException(){

            student.setName(null);

      }

}

Resultado:

resultaopunittest

Classe com o método main

Fiz uma pequena classe com método main, para quem não sabe unit test:

public class MainTest {

      public static void main(String[] args) {

            ApplicationContext  applicationContext = new ClassPathXmlApplicationContext(“config/springconfiguration.xml”);

            Student bean = (Student) applicationContext.getBean(“student”);

            bean.setName(“lopes”);

            bean.teste();           

      }

} 

O resultado será diferente pq as inovações são diferentes:

resultadoaopmaintest

 

Bom, pessoal. Vou ficando por aqui e espero que tenham gostado do post.

Abraços,

Série Spring: Spring Aspect Object Programming – AOP

olá Pessoal,

O post de hoje veremos com brincar com AOP. Opsss… O que é isso? Veremos um pouco mais a seguir a utilidade de usar AOP e faremos um exemplo simples para vê-lo em ação.

lets go…

AOP – Aspect Object Programming

Em poucas palavras a orientação a aspectos surgiu para eliminar os chamados de cross cutting concerns, ou seja, aquele código que é necessário, mas que não faz parte das principais obrigações do objeto, por exemplo: logging, transação etc. E para isso precisamos entender trêsp ontos apenas:

 

1. Advice: separa o código nada ver em um lugar especifico

2. join point: define dentro do advice o momento que o código separado executa

3.point cuts: é onde será feito.

Então o advice é o que será feito. O joint cuts é quando será feito. E o point cuts é o onde será feito.

 

Antes de começarmos colocar mão na masa precisamos fazer download do .jar do AspectJ http://www.eclipse.org/aspectj/downloads.php após baixar, descompacte o .jar com o winrar por exemplo vá na pasta lib copie os .jars existentes e adicione ao seu projeto.

 

Precisamos também do AOP Alliance http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.aopalliance&version=1.0.0  faça o download e adicione ao seu projeto.

 

Adicione também o commons-logging-1.x http://commons.apache.org/logging/

 


AOPBankProject

Na diferente do que vimos no primeiro post. O objetivo de nossa aplicação é apenas logar informações quando um saque ou desposito for realizado. No exemplo logamos isso no console, em uma aplicação logariamos isso em arquivo de log por exemplo.

 

 

Desenvolvimento

 

1. crie o bean a seguir:

 

package br.com.camilolopes.bean;

import java.math.BigDecimal; 

public class Client  { 

                public void sacar(BigDecimal value) {

                               System.out.println(“Saque realizado com sucesso ” + value);

                }

                public void depositar(BigDecimal value) {

                               System.out.println(“Deposito realizado ” + value);

                }}

 

2. Agora vamos passar a resposabilidade para o Spring cuidar do nosso bean:

 

<?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:aop=”http://www.springframework.org/schema/aop”

                xsi:schemaLocation=”http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.2.xsd”>

<bean id=”client”  />

<bean class=”br.com.camilolopes.manager.ManagerTransationAccount”/>

<aop:aspectj-autoproxy />

</beans>

 

Há uma pequena mudança no nosso arquivo xml, observe que adicionamos ao cabeçalho xmlns e http referente aop. E em seguida criamos  um bean para cada classe. A ManagerTransationAccount ainda não criamos, mas não há problemas em colocarmos ela no xml. Vamos criar um pouco mais adiante. A tag de proxy que adicionamos acima estamos falando para o Spring fazer o trabalho duro de criar proxy para nós.

Agora vamos criar a nossa classe que vai controlar as mensagens, ou seja, tudo que acontece na conta será logado:

 

@Aspect

public class ManagerTransationAccount {

                @Pointcut(“execution(* *.sacar(..)”)

                public void transacao(){}               

                @Before(“transacao()”)

                public void saque(){

//                           poderia logar a info no arquivo de log

                               System.out.println(“Transação de saque inicializada”);

                }

                @AfterReturning(“transacao()”)

                public void retirada(){

                               System.out.println(“Transação de saque concluida com sucesso”);

                }

               

                @Pointcut(“execution(* *.depositar(..))”)

                public void deposito(){}

               

                @Before(“deposito()”)

                public void depositar(){

                               System.out.println(“Transação de deposito iniciada”);

                }

               

                @AfterReturning(“deposito()”)

                public void depositado(){

                               System.out.println(“deposito realizado com sucesso”);

                }

}

 

Explicando:

Bem, anotação na classe é bem intuitiva certo? é preciso dizer que essa classe é orientada a aspect. Dai por isso anotação no inicio dela. Em seguida criamos um método da classe onde tudo começa o segredo está na anotação. Observe que é um pointcut, ou seja, onde será feito o trabalho e ali estamos dizendo que será feito quando o método sacar for chamado de qualquer classe passando qualquer parametro.

 

Atenção: Nenhum método criado nessa classe tem relação com os métodos que criamos na interface Machine. Poderiamos aqui chamar nosso método de qualquer coisa. O segundo que criamos e chamamos de saque que leva anotação @Before diz o seguinte: antes de chamar transacao(), ou seja, o métod que tem o pointcut, execute este aqui, ou seja, vai imprimir no console uma mensagem. Mas, poderiamos gravar uma informação no arquivo de log.

As demais anotações falam por si só.

 

Agora vamos testar, crie uma classe com método main:

public class MainBankMachine {

                public static void main(String[] args) {

                               ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“conf/springconfiguration.xml”);

                               Client bean = (Client) applicationContext.getBean(“client”);

                               bean.sacar(BigDecimal.TEN);

                              

                }

}

 

O resultado

 

 aopresult

Agora fazendo deposito e saque:

 

aopresult2

      public static void main(String[] args) {

            ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“conf/springconfiguration.xml”);

            Client bean = (Client) applicationContext.getBean(“client”);

            bean.sacar(BigDecimal.TEN);

            bean.depositar(BigDecimal.ONE);

      }

bom, é isso. Bem mais simples e fácil de dar manutenção não?

Vou ficando por aqui espero que tenham gostado do post.

abracos, see ya!!!