Arquivos da categoria: JSF

Injeção de Dependência: comparação de desempenho

No presente post procurar-se-á demonstrar uma comparação entre injeção de dependência de dois grandes Frameworks, o JSF e o Spring. Para efeito de comparação também foi testada uma versão do aplicativo web com JSF sem o uso de injeção de dependência.

No desenvolvimento Web, diferentemente do desenvolvimento de aplicativos para Desktop, os sistemas muitas vezes possuem dezenas de milhares de usuários simultaneamente, isso exige um grande desempenho das aplicações.

Sendo assim a verificação do desempenho de diferentes formas de implementações, utilizando JSF com e sem injeção de dependência, que é uma forma de IoC (Inversion of Control – Inversão de Controle), e Spring, é importante e aponta para possibilidades mais adequadas, considerando as diferenças de desempenho entre os frameworks citados.

Os sistemas serão submetidos a testes de stress e desempenho. Para realização desses testes foi utilizado a ferramenta JMeter, uma ferramenta que diante das crescentes necessidades por performance vem sendo muito utilizada. Apache JMeter pode ser usado para testar o desempenho tanto em recursos estáticos quanto dinâmicos (arquivos, Servlets, scripts Perl, Java Objects, Bases de Dados, Consultas SQL, servidores FTP e muito mais).

Para o presente trabalho foram realizados dois testes para cada sistema desenvolvido, primeiro com 1000 usuários e o segundo com 4000 usuários. Esses dois testes foram realizados da mesma maneira com os três sistemas desenvolvidos (Spring com IoC, JSF com e sem IoC). Foram realizados testes com o máximo de 4000 mil usuários pois, o sistema após esse número apresentava a exceção “java.lang.OutOfMemoryError: Java heap apace” tornando impossível a realização de testes com maior número de usuários.

Como pode ser visto logo abaixo, o JMeter permite entre outras características as seguintes:

Tempo da amostra – tempo de resposta da aplicação;

Desvio – dispersão dos valores em relação à média;

Porcentagem de erro – porcentagem de problemas nas respostas;

Vazão – o número de operações que o sistema é capaz de completar em um dado período de tempo;

Carga Máxima do servidor – uso do processador pelo servidor;

Memória Máxima do servidor – uso de memória pelo servidor.

Tabela 1: Comparativo de desempenho com 1000 threads

Item Spring JSF com IoC JSF sem IoC
Tempo da amostra 75ms 74ms 39ms
Desvio 49ms 40ms 19ms
% de erro 0 % 0% 0%
Vazão 19,8/seg 19,8/seg 19,8/seg
Carga Máx. servidor ~37% ~60% ~50%
Memória Máx. servidor ~75% ~100% ~98%

 

Tabela 2: Comparativo de desempenho com 4000 threads

Item Spring JSF com IoC JSF sem IoC
Tempo da amostra 41ms 39ms 39ms
Desvio 89ms 25ms 18ms
% de erro 0%  0% 0%
Vazão 18,1/seg 19,6/seg 19,8/seg
Carga Máx. servidor ~48% ~35% ~48%
Memória Máx. servidor 95% ~80% ~90%

Através dos dados obtidos com os testes é possível identificar onde cada abordagem de desenvolvimento obteve um melhor desempenho com respeito à performance. Na tabela 1 e 2, foram agrupados os principais quesitos com respeito ao desempenho da aplicação para que pudéssemos analisar de forma mais clara.
Tempo da Amostra – Com relação a tempo, que seria o tempo de resposta da aplicação, na tabela acima temos a média de cada um. Observamos que o JSF sem Injeção de Dependência obteve resultados um pouco melhores, sendo em média mais rápido.
A porcentagem de erro ou problemas ao acessar a aplicação foi de zero por cento em todas as abordagens apresentadas.
A Vazão não foi muito diferente entre um e outro ficando novamente o JSF sem IoC um pouco à frente dos demais, mas apenas no teste com 4000 usuários, sendo praticamente insignificante a diferença haja vista que a própria rede pode apresentar oscilações na transferência de dados.
Agora com relação ao servidor de aplicações Tomcat, a carga do sistema obteve resultados na faixa de 35% a 60%, entretanto, não somos capazes de inferir nada com relação, pois em todos os testes houve oscilações durante o intervalo observado, sendo, que o Spring conseguiu se manter mais estável. Com relação ao uso da memória também não houve muita diferença.
Os testes foram realizados com o grupo máximo de 4000 usuários devido a estouro de memória no sistema quando utilizado por um grupo maior de usuários, apresentando a seguinte exceção: “java.lang.OutOfMemoryError: Java heap apace”. Com o número de usuários máximo utilizado nos testes, embora tenha havido algumas diferenças nos resultados, os sistemas se comportaram bem, não gerando gargalos nem indisponibilidade. Podemos perceber diante disso que com a melhora cada vez maior das técnicas de desenvolvimento de Frameworks e linguagens de programação o nível de qualidade se mantém quase igual, claro havendo algumas metodologias e facilidades diferenciadas em cada um.

CONCLUSÃO

Com todas as metodologias e técnicas utilizadas atualmente no desenvolvimento de ferramentas para auxílio dos programadores de sistemas, e até mesmo a maior especialização e estudo por parte das pessoas envolvidas nesse processo de desenvolvimento, tornou-se possível, excluindo algumas especificidades, que os níveis dessas ferramentas, como já dito anteriormente, quanto a desempenho se tornem muito parecidas, não havendo uma diferença muito grande.

O presente trabalho mostrou exatamente que as funcionalidades básicas, como é o caso da injeção de dependência, já estão bem consolidadas na maior parte dos Frameworks, logo, salvo funcionalidade muito específica, que seja provida por apenas um Framework, qualquer um dos Frameworks demonstrados aqui seria muito importante para um sistema em desenvolvimento e não haveria grandes problemas por adotar um ou outro, notando apenas que a injeção de dependência é um padrão de projeto e como tal já foi provado por anos de experiência em desenvolvimento de software, que é a forma mais indicada para desenvolvimento de sistemas complexos por facilitar muito o trabalho, tendo sido utilizada uma versão sem injeção de dependência no trabalho apenas por questões comparativas (mesmo que fosse muito mais eficiente não seria indicada por muitos outros fatores).

 

Injeção de Dependência no JSF 2

Como  já  é  do  conhecimento  de  qualquer  desenvolvedor,  cada  classe  em  Java  possui características  específicas  possuindo  seus  atributos  próprios  e  métodos  relacionados  com  suas características e funcionalidades  que precisará realizar. Em  qualquer  aplicação  Orientada  a  Objetos  muitas  vezes  é  necessário  que  uma  classe  use serviços de outras classes. Para que ocorra essa troca de funcionalidades é preciso que uma classe possua a referência da outra classe que deseja usar. Normalmente faríamos isso instânciando a classe ou seja daríamos um ‘new’ no nosso objeto, entretanto hoje será mostrada uma forma para se fazer isso através da Injeção de Dependência do JSF.

Um bom motivo para usarmos Injeção de Dependência em nosso projeto é o desacoplamento do nosso código,  facilidade para reuso e também facilidade para realizar testes.

A  partir  do  JSF  2  isso  ficou  muito  mais  simples  de  ser  feito,  podemos  usar  a  Injeção de Dependência  disponibilizada  por  ele  apenas  utilizando  anotações  em  cima  das  nossas  classes,  abaixo segue uma exemplificação de como podemos fazer isso:

@ManagedBean(name="veiculo")
@ApplicationScoped
public class VeiculoDaoImpl implements VeiculoDao{

//Atributos
//Métodos

//Gets e Sets

}

Primeiramente, damos um nome para no ManagedBean, no exemplo chamamos de veiculo mas pode ser qualquer nome. Esse ManagedBean é a classe que queremos usar, ou seja, queremos injetar essa classe para que a outra classe possa se utilizar de suas funcionalidades.
Note que VeiculoDao é apenas uma interface nela apenas colocamos as assinaturas dos métodos que vamos posteriormente implementar na classe VeiculoDaoImpl, é extremamente importante de criarmos uma interface para cada classe, pois o JSF injeta apenas as os métodos que estão declarados nas interfaces.
Por fim precisamos apenas injetar a classe VeiculoDaoImpl, para isso procedemos da seguinte forma:

@ManagedBean(name="vendaController")
@ApplicationScope
public class VendaController implementes Serializable{

@ManagedProperty(value="#{veiculo}")
private VeiculoDao veiculoDao;

//Gets e Sets

}

Esse segundo ManagedBean é onde nós iremos injetar a nossa classe VeiculoDaoImpl, para fazer isso apenas utilizamos a anotação @ManagedProperty e na propriedade value colocamos o nome dado anteriormente ao nosso ManagedBean, ou seja, “veiculo” outro detalhe importante é criar os Gets e Sets para a classe a ser injetada. Pronto com apenas algumas linhas acabamos de realizar a injeção de dependência do JSF 2.

Personalizar Tema PrimeFaces

logo-jquery

 

 

 

 

 

 

Uma dica muito interessante para quem usa PrimeFaces. Navegando, hoje no site do Jquery, encontrei um recurso para personalizar os temas do PrimeFaces, com ele é possível editar desde fonte, as cores dos temas e até mesmo mudar o formato dos cantos dos componentes de acordo com o seu gosto e depois de criado o novo tema é só realizar o download e usar em seus projetos.

Para quem interessar segue o link do Jquery.

Disponibilizando ViewScope para Spring

spring e jsf

Quem trabalha com JSF sabe que existem escopos para seus Managed Beans, e que eles devem ser bem definidos conforme o papel de cada Managed Bean na aplicação. Esse tal de “escopo” define o tempo de vida desse objeto(o Managed Bean) dentro da aplicação.

A partir do JSF 2.0 foi implementado um novo tipo de escopo, chamado de ViewScope. Este novo escopo veio para suprir a necessidade de se ter um tempo de vida dos Managed Beans um pouco maior do que o Request e menor que o Session. O uso do ViewScope é muito recomendado pois evita que um ManagedBean fique instanciado durante a sessão inteira do usuário(caso do SessionScope) mesmo que não esteja mais sendo usado, e possibilita guardar dados enquanto o usuário não troca de página(UIViewRoot), mesmo utilizando requisições ajax(o que não é possível com o RequestScope).

Grande parte das aplicações possuem frameworks, como o Spring, para gerenciar seus Beans. Logicamente, devem ser utilizadas as configurações do framework para o gerenciamento dos mesmos. No caso do Spring, (ainda) não existe um escopo com a mesma lógica do ViewScope do JSF, mas como todo bom framework, pode-se customizar um tipo de escopo e fazer uso dele normalmente na aplicação. É claro que para isso é necessário implementá-lo.

Na empresa onde trabalho utilizamos Spring e tivemos a necessidade de modificar alguns escopos de Session para View. Encontramos um post(em inglês) que fala sobre isso e exemplifica como implementar e disponibilizar um “ViewScope” para o Spring.

Segue aí os passos para implementar seu ViewScope para o Spring.

1. Implementar a classe responsável pelo gerenciamento dos Beans:

import java.util.Map;

import javax.faces.context.FacesContext;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.web.context.request.FacesRequestAttributes;

public class ViewScope implements Scope {

	public static final String VIEW_SCOPE_CALLBACKS = "viewScope.callbacks";

	public synchronized Object get(String name, ObjectFactory<?> objectFactory) {
		Object instance = getViewMap().get(name);
		if (instance == null) {
			instance = objectFactory.getObject();
			getViewMap().put(name, instance);
		}
		return instance;
	}

	public Object remove(String name) {
		Object instance = getViewMap().remove(name);
		if (instance != null) {
			Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
			if (callbacks != null) {
				callbacks.remove(name);
			}
		}
		return instance;
	}

	public void registerDestructionCallback(String name, Runnable runnable) {
		Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
		if (callbacks != null) {
			callbacks.put(name, runnable);
		}
	}

	public Object resolveContextualObject(String name) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
		return facesRequestAttributes.resolveReference(name);
	}

	public String getConversationId() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
		return facesRequestAttributes.getSessionId() + "-" + facesContext.getViewRoot().getViewId();
	}

	private Map<String, Object> getViewMap() {
		return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
	}
}

2. Para poder “destruir” o Bean é necessário colocá-lo em algum local em que seja possível recuperá-lo posteriormente. A classe acima implementa o método registerDestructionCallback, responsável por registrar uma chamada de destruição ao Bean. Essa chamada será armazenada no viewMap da ViewRoot(nossa página que será mostrada), dentro de um Map para que possamos acessá-lo através de uma chave que será o nome do Bean. Graças ao mecanismo de Listeners, conseguimos inserir um novo objeto(no nosso caso um novo Map) dentro do viewMap da página.

Com a implementação da classe abaixo estaremos tratando de dois eventos simultaneamente: assim que o viewMap é construído(na inicialização da página ou PostConstructViewMapEvent) inserimos nosso “repositório” de Beans com ViewScope e seus respectivos destrutores, que será utilizado pelo método registerDestructionCallback, e pouco antes dele ser destruído(PreDestroyViewMapEvent) resgatamos os Beans com ViewScope inseridos no nosso “repositório” criado anteriormente e chamamos seus destrutores.

import java.util.HashMap;
import java.util.Map;

import javax.faces.component.UIViewRoot;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PostConstructViewMapEvent;
import javax.faces.event.PreDestroyViewMapEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.ViewMapListener;

public class ViewScopeCallbackRegistrer implements ViewMapListener {

	public void processEvent(SystemEvent event) throws AbortProcessingException {
		if (event instanceof PostConstructViewMapEvent) {
			PostConstructViewMapEvent viewMapEvent = (PostConstructViewMapEvent) event;
			UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent();
			viewRoot.getViewMap().put(ViewScope.VIEW_SCOPE_CALLBACKS, new HashMap<String, Runnable>());
		} else if (event instanceof PreDestroyViewMapEvent) {
			PreDestroyViewMapEvent viewMapEvent = (PreDestroyViewMapEvent) event;
			UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent();
			Map<String, Runnable> callbacks = (Map<String, Runnable>) viewRoot.getViewMap().get(ViewScope.VIEW_SCOPE_CALLBACKS);
			if (callbacks != null) {
				for (Runnable c : callbacks.values()) {
					c.run();
				}
				callbacks.clear();
			}
		}
	}

	public boolean isListenerForSource(Object source) {
		return source instanceof UIViewRoot;
	}
}

3. Disponibilizar a nossa classe ViewScope para o Spring, inserindo o código abaixo no seu applicationContext.xml:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="view">
                <bean class="seupackage.ViewScope"/>
            </entry>
        </map>
    </property>
</bean>

4. Registrar nossa classe ViewScopeCallbackRegistrer nos listeners do Faces, inserindo o código abaixo no faces-config.xml:

<system-event-listener>
    <system-event-listener-class>seuPackage.ViewScopeCallbackRegistrer</system-event-listener-class>
    <system-event-class>javax.faces.event.PostConstructViewMapEvent</system-event-class>
    <source-class>javax.faces.component.UIViewRoot</source-class>
</system-event-listener>

<system-event-listener>
    <system-event-listener-class>seuPackage.ViewScopeCallbackRegistrer</system-event-listener-class>
    <system-event-class>javax.faces.event.PreDestroyViewMapEvent</system-event-class>
    <source-class>javax.faces.component.UIViewRoot</source-class>
</system-event-listener>

Basta agora utilizar a anotação @Scope(“view”) sobre seus Managed Beans e eles passarão a ter o comportamento do @ViewScope, mas agora gerenciados pelo Spring.

Bons códigos!!!

Fonte: http://www.harezmi.com.tr/spring-view-scope-for-jsf-2-users/

Formatando campos monetários no JSF com jQuery

Em nossas aplicações é comum a necessidade de trabalhar com valores monetários(dinheiro). O Java não possui um tipo específico para trabalhar com tipos monetários, ficando a cargo do programador decidir se irá utilizar classes do tipo Float ou Integer ou qualquer outra.

Mas uma coisa é certa: não interessa se nas suas classes Java é utilizado Double, Integer, Float ou BigDecimal. Para o usuário, que vai ver a tela final do sistema, é necessário apresentá-la de forma intuitiva e que o mesmo não precise pensar muito para descobrir o que cada componente faz na tela.

Nesse post iremos demonstrar como utilizar um plugin do jQuery(jQuery Price Format) para formatar os campos que terão valores monetários em uma página JSF.

Partimos do princípio de que o(a) leitor(a) esteja um pouco familiarizado com JSF. Neste exemplo vamos utilizar o tipo Float para armazenar nosso valor monetário, mas poderia ser qualquer outra. Este valor será armazenado diretamente no Managed Bean.

package br.com.exemplo.ManagedBean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class ExemploMonetarioMB {

	private Float valorMonetario = 0f;

	public String mostraValor() {
		return "mostraValor.xhtml";
	}

	public Float getValorMonetario() {
		return valorMonetario;
	}

	public void setValorMonetario(Float valorMonetario) {
		this.valorMonetario = valorMonetario;
	}

}

Vamos precisar do jQuery e do plugin jQuery Price Format. Após o download dos mesmos, criamos uma pasta chamada “js” dentro de WebContent/resources para colocarmos nossos arquivos JavaScript. Precisamos agora chamar os arquivos “.js” para a nossa página.

<h:outputScript name="jquery.min.js" library="/js" />
<h:outputScript name="jquery_price.js" library="/js" />

Na tela temos somente um campo que irá conter o valor digitado pelo usuário.

<h:form>
    <h:outputLabel value="Digite o valor:" />
    <h:inputText value="#{exemploMonetarioMB.valorMonetario}" converter="dinheiroConverter" styleClass="monetario" />
    <h:commandButton value="Ok" action="#{exemploMonetarioMB.mostraValor}" />
</h:form>

Graças  ao jQuery, com um comando conseguimos formatar mais de um componente, caso houvesse, utilizando o seletor de classe. Colocamos uma classe(neste caso “monetario”, mas poderia ser qualquer outra) nos componentes que queremos formatar com o jQuery Price Format, e chamamos a função assim que a página estiver carregada, utilizando “(document).ready”.

<script type="text/javascript">

	 jQuery(document).ready(function(){
		jQuery('.monetario').priceFormat({
			prefix:'R$ '
		});
	});
</script>

Agora, está faltando somente implementar o nosso Converter, que será responsável por fazer a conversão dos valores da tela para o Java e vice-versa.

package br.com.exemplo.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(forClass = Float.class, value = "dinheiroConverter")
public class DinheiroConverter implements Converter {

	@Override
	public Object getAsObject(FacesContext context, UIComponent component,
			String value) {
		if (value != null && !value.equals("")) {
			String str = value.trim();

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < str.length(); i++) {
				char ch = str.charAt(i);
				if (Character.isDigit(ch) || ch == '.') {
					sb.append(ch);
				}
			}

			return new Float(sb.toString());
		}
		return null;
	}

	@Override
	public String getAsString(FacesContext context, UIComponent component,
			Object value) {
		if (value != null) {
			String prefixoMoeda = "R$ ";
			StringBuilder s = new StringBuilder(value.toString());
			if (s.substring(s.indexOf(String.valueOf('.'))).length() == 2) {
				s.append("0");
			}

			for (int i = s.indexOf(String.valueOf('.')) - 3; i > 0; i -= 3) {
				s.insert(i, ',');
			}
			return prefixoMoeda + " " + s.toString();
		}
		return "";
	}
}

Dessa forma, tem-se como resultado a tela de inserção do valor:

E após clicar em “Ok” mostramos os valores da forma nativa, em nosso caso Float, e utilizando o Converter:

 

Você pode baixar o projeto(para Eclipse) neste link.