Turbinando o Mentawai com Spring
este artigo abordará uma das formas de integrar o Spring com o Mentawai
Olá pessoal, este artigo abordará uma das formas de integrar o Spring com o Mentawai, antes disso surge uma pergunta;
Pra que usar o spring se o Mentawai possui IoC? Muitos são fanáticos por Spring, outros gostam de não acoplar seu código com Framework etc.
Eu particularmente gostei bastante das configurações via annotations, ainda mais por se tratar de JPA + Hibernate, que é o que eu utilizo com frequencia.
Em resumo o que teremos no final deste artigo é um projeto web com as seguintes tecnologias:
Mentawai
Hibernate + Annotations
Postgresql
Spring + JPA
Sem mais conversa, vamos ao que interessa!
Neste artigo não abordarei o uso efetivo de Spring nem do Mentawai, apenas a integração entre os dois frameworks.
Utilizo do Maven para resolução de dependências, então para quem ainda não conhece o Maven, é bom dar um olhada, pois esse cara vale a pena.
Entendo que voce ja conhece o Maven e sabe criar um projeto web com o mesmo, proceguimos então de um projeto novo web com o Maven.
Este é o pom.xml
view source
print?
001 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
002 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
003 <modelVersion>4.0.0</modelVersion>
004 <groupId>org.com.mentaframework</groupId>
005 <artifactId>mentaspring</artifactId>
006 <packaging>war</packaging>
007 <version>0.0.1-SNAPSHOT</version>
008 <name>Mentaspring</name>
009 <url>http://maven.apache.org</url>
010
011 <properties>
012 <spring.version>2.5</spring.version>
013 </properties>
014
015 <dependencies>
016 <dependency>
017 <groupId>junit</groupId>
018 <artifactId>junit</artifactId>
019 <version>4.7</version>
020 <scope>test</scope>
021 </dependency>
022
023 <dependency>
024 <groupId>org.mentaframework</groupId>
025 <artifactId>mentawai</artifactId>
026 <version>1.15</version>
027 </dependency>
028
029 <dependency>
030 <groupId>postgresql</groupId>
031 <artifactId>postgresql</artifactId>
032 <version>8.4-701.jdbc4</version>
033 </dependency>
034
035 <dependency>
036 <groupId>org.springframework</groupId>
037 <artifactId>spring</artifactId>
038 <version>${spring.version}</version>
039 </dependency>
040
041 <dependency>
042 <groupId>org.springframework</groupId>
043 <artifactId>spring-aop</artifactId>
044 <version>${spring.version}</version>
045 </dependency>
046
047 <dependency>
048 <groupId>org.aspectj</groupId>
049 <artifactId>aspectjrt</artifactId>
050 <version>1.6.8</version>
051 </dependency>
052
053 <dependency>
054 <groupId>org.aspectj</groupId>
055 <artifactId>aspectjweaver</artifactId>
056 <version>1.6.8</version>
057 </dependency>
058
059 <dependency>
060 <groupId>org.hibernate</groupId>
061 <artifactId>hibernate-core</artifactId>
062 <version>3.3.2.GA</version>
063 </dependency>
064
065 <dependency>
066 <groupId>org.hibernate</groupId>
067 <artifactId>hibernate-entitymanager</artifactId>
068 <version>3.4.0.GA</version>
069 </dependency>
070
071 <dependency>
072 <groupId>org.hibernate</groupId>
073 <artifactId>hibernate-annotations</artifactId>
074 <version>3.4.0.GA</version>
075 </dependency>
076
077 <dependency>
078 <groupId>cglib</groupId>
079 <artifactId>cglib</artifactId>
080 <version>2.2</version>
081 </dependency>
082
083 <dependency>
084 <groupId>org.slf4j</groupId>
085 <artifactId>slf4j-log4j12</artifactId>
086 <version>1.5.8</version>
087 </dependency>
088
089 <dependency>
090 <groupId>javax.annotation</groupId>
091 <artifactId>jsr250-api</artifactId>
092 <version>1.0</version>
093 </dependency>
094
095 <dependency>
096 <groupId>commons-dbcp</groupId>
097 <artifactId>commons-dbcp</artifactId>
098 <version>1.2.2</version>
099 </dependency>
100
101 </dependencies>
102 <build>
103 <finalName>mentaspring</finalName>
104 </build>
105 </project>
O que o Maven faz é pegar todas as dependencia descritas acima e ediconá-las ao seu classpath, se ainda não houver o .jar na sua máquina
ele se encarrega de baixar automaticamente. caso não esteja usando o maven, baixe os jars e coloque na pasta lib de sua aplicação.
Agora precisamos configurar nosso persistence.xml, para quem não sabe, este arquivo configura uma unidade de persistência, ou seja, um datasource JPA.
este arquivo deve estar dentro da pasta META-INF.
view source
print?
01 <persistence xmlns="http://java.sun.com/xml/ns/persistence"
02 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
03 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
04
05 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
06
07 version="1.0">
08 <persistence-unit name="PU" transaction-type="RESOURCE_LOCAL">
09 <provider>org.hibernate.ejb.HibernatePersistence</provider>
10 <properties>
11 <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
12 <property name="hibernate.connection.username" value="exemplo" />
13 <property name="hibernate.connection.password" value="exemplo" />
14 <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/exemplo" />
15 <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
16 <property name="hibernate.show_sql" value="true" />
17 </properties>
18 </persistence-unit>
19 </persistence>
Repare que o nome de nossa unidade de persistência é “PU”, um nome qualquer.
Após termos configurado nossa unidade de persistência, já podemos começar a configurar o spring, segue o xml de configuração do Spring:
view source
print?
01 <?xml version="1.0" encoding="UTF-8"?>
02 <beans xmlns="http://www.springframework.org/schema/beans"
03 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
04 xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
05 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
06 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
07 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
08 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
09
10 <!-- Ativa varios listeners do spring que varrerão sua applicação atraz de classes anotadas. -->
11 <context:annotation-config />
12
13 <!-- Diz onde fica o pacote raiz para o spring começar a efetuar a sua busca por classes anotadas -->
14 <context:component-scan base-package="com.barba" />
15
16 <!-- Ativa o JTA do spring por annotation -->
17 <tx:annotation-driven transaction-manager="txManager" />
18
19 <!-- Gerenciador de transacoes baseado em JPA -->
20 <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
21 <property name="entityManagerFactory" ref="entityManagerFactory" />
22 </bean>
23
24 <!-- Fabrica de entity managers -->
25 <!-- Repare o nome da persistenceUnit -->
26 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
27 <property name="persistenceUnitName" value="PU"></property>
28 </bean>
29
30 </beans>
Voilá! temos o Spring com JPA e JTA configurados, e tambem mostramos ao spring onde procurar seus beans anotados. Com isso o Spring já é
capaz de criar o EntityManager.
Pesou que eu tinha esquecido do Mentawai? hehe, agora vem a parte mais fácil, Aqui voce encontra
um quickstart de um projeto com Mentawai, mas como é bem simples, vou colocá-lo aqui tambem.
Segue o web.xml da nossa aplicação:
view source
print?
01 <?xml version="1.0" encoding="UTF-8"?>
02 <web-app 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">
03 <display-name>Menta Spring</display-name>
04
05 <!-- Configurações do Spring -->
06 <context-param>
07 <param-name>contextConfigLocation</param-name>
08 <param-value>WEB-INF/applicationContext.xml</param-value>
09 </context-param>
10
11 <filter>
12 <filter-name>jpaFilter</filter-name>
13 <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
14 </filter>
15
16 <filter-mapping>
17 <filter-name>jpaFilter</filter-name>
18 <url-pattern>/*</url-pattern>
19 </filter-mapping>
20
21 <listener>
22 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
23 </listener>
24
25 <listener>
26 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
27 </listener>
28 <!-- Configurações do Spring -->
29
30 <!-- The Mentawai controller -->
31 <servlet>
32 <servlet-name>Controller</servlet-name>
33 <servlet-class>org.mentawai.core.Controller</servlet-class>
34 <load-on-startup>1</load-on-startup>
35 </servlet>
36
37 <!-- You must choose an extension to indicate a mentawai action -->
38 <servlet-mapping>
39 <servlet-name>Controller</servlet-name>
40 <url-pattern>*.mtw</url-pattern>
41 </servlet-mapping>
42 <!-- The Mentawai controller -->
43
44 </web-app>
Uma breve explição sobre as configurações do spring:
contextConfigLocation
Diz onde esta o nosso arquivo de configuração do spring.
jpaFilter: org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
É um filtro do spring que abre o EntityManager (session) no inicio do request e o fecha no final da rederização da view. muito util para utilização de lazy.
org.springframework.web.context.request.RequestContextListener
Não é obrigatório, mas abilita a utilização da anotação Scope(“scope”) nas actions, se o scope for “session” será criada uma action para cada session, se for request,
será criada uma instancia da action para cada request, algo parecido com as sticky actions do Mentawai.
org.springframework.web.context.ContextLoaderListener
Este cara é o responsável por inicializar o Contexto do Spring junto com o startup da aplicação.
As outras linhas configuram o controller do Mentawai e seu mapeamento.
Agora precisamos do ApplicationManager do Mentawai que vai fazer o serviço MVC e controlar flow de páginas.
view source
print?
01 public class ApplicationManager extends org.mentawai.core.ApplicationManager {
02
03 @Override
04 public void loadActions() {
05
06 spring("/HelloAction", "helloAction").fwdOk("/jsp/hello.jsp");
07
08 }
09
10 }
Simples action:
view source
print?
01 package com.barba.actions
02
03 @Controller
04 @Scope("request")
05 public class HelloAction extends BaseAction {
06
07 @Resource
08 ProductService productService;
09
10 public String execute() throws Exception {
11
12 output.setValue("framework", "The Mentawai");
13
14 return SUCCESS;
15 }
16
17 public ArrayList<Product> getProducts(){
18 return productService.findAll();
19 }
20
21 }
Agora sim precisamos de um pouco mais de explicações =).
A anotação @Controller do spring, registra esta classe como sendo uma action para o Mentawai, como não foi passado um parametro com o nome,
assume-se nome da action. like @Controller(“helloAction”) no caso.
A anotação @Scope(“request”) do spring, cria uma estancia desta action a cada request, o que normalmente é utilizado.
A anotação @Resource tambem do spring, diz que aquela variável deverá ser preenchida com uma instancia daquela classe, ou seja, aqui
começa a mágina do IoC.
A a classe ProductService é a nossa classe que fará acesso ao banco de dados.
view source
print?
01 package com.barba.services
02
03 @Service
04 public class ProductService {
05
06 @PersistenceContext
07 private EntityManager entityManager;
08
09 public ArrayList<Product> findAll() {
10
11 Query query = entityManager.createQuery("from Product");
12
13 return (ArrayList<Product>) query.getResultList();
14
15 }
16
17 }
A anotação @Service, registra no spring um componente service que poderá ser utilizado em qualquer lugar tendo
apenas que usar a anotação @Resource como foi utilizado na nossa action para referenciá-lo.
Por ultimo, a notação @PersistenceContext é uma anotação JPA que diz onde queremos o EntityManager para acessarmos o banco de dados.
Voltando um pouco agora na nossa configuração no ApplicationManager:
spring(“/HelloAction”, “helloAction”).fwdOk(“/jsp/hello.jsp”);
/HelloAction = Mapeamento da url, ao acessarmos por exemplo /contexto/HelloAction.mtw
helloAction = Nome do nosso controller (action) que foi mapeado pelo Spring via anotação @Controller.
fwdOk(“/jsp/hello.jsp”) = Em caso de sucesso, será feito um forward para /jsp/hello.jsp. obs: Existem várias consequencias e formas de configuração que podem ser utilizadas.
Agora só falta nossa hello.jsp:
view source
print?
01 <%@ page contentType="text/html; charset=ISO-8859-1" %>
02 <%@ taglib uri="http://www.mentaframework.org/tags-mtw/" prefix="mtw" %>
03
04 <html>
05
06 <head>
07 <title>OK</title>
08 </head>
09
10 <body>
11
12 <h3>EL</h3>
13 $
14
15 <h3>Menta Tag</h3>
16 <mtw:out value="framework" />
17
18 <h3>Products</h3>
19 <table>
20
21 <mtw:list value="helloAction.products">
22 <mtw:loop var="p">
23 <tr>
24 <td><mtw:out value="name" /></td>
25 <td>${p.name}</td>
26 </tr>
27 </mtw:loop>
28 </mtw:list>
29
30 </table>
31
32 </body>
33
34 </html>
Temos no exemplo duas formas de mostrar o valor jogado pelo output da action do Mentawai, com EL e com Menta Tags.
Perai, mas e aquele mtw:list value=”helloAction.products” ?
É isso mesmo, a página JSP no momento da renderização esta indo diretamente em nossa action e executando o método getProducts().
Poderíamos tambem jogar a lista no output e pegá-la normalmente com EL ou com a própria Tag mtw:list.
Segue classe Product, nada de diferente, apenas Anotações.
view source
print?
01 package com.barba.pojo
02
03 @Entity
04 @Table(name="product", schema="exemplo")
05 public class Product {
06
07 private int id;
08 private String name;
09
10 public Product() {
11 }
12
13 @SequenceGenerator(name = "generator", sequenceName = "exemplo_id_seq", allocationSize = 1)
14 @Id
15 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
16 public int getId() {
17 return id;
18 }
19
20 public void setId(int id) {
21 this.id = id;
22 }
23
24 public String getName() {
25 return name;
26 }
27
28 public void setName(String name) {
29 this.name = name;
30 }
31 }
Integrar mais módulos do spring é questão de saber o utilizar o spring, tenho inclusive spring-aop em um ambiente com este.
Bom é isso pessoal, até a próxima.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Vídeo