java - que - tecnologias para el desarrollo de aplicaciones web cuadro comparativo
Describe la arquitectura que utilizas para las aplicaciones web Java (10)
Aquí están mis 5 centavos
Presentación
Android, Angular.JS WebClient, OAUTHv2
API
REST, Jersey (JAX-RS), Jackson (JSON des / serialización), DTO-objects (diferente de los modelos de lógica de negocios)
Lógica de negocios
Primavera para DI y manejo de eventos. Enfoque DDD-ish de los objetos modelo. Las tareas más largas se descargan con SQS en los módulos de trabajador.
DAO
Modelo de repositorio con Spring JDBC-templates para almacenar entidades. Redis (JEDIS) para tablas de clasificación, utilizando listas ordenadas. Memcache para Token Store.
Base de datos
MySQL, Memcached, Redis
¡Compartamos arquitecturas de aplicaciones web basadas en Java!
Existen muchas arquitecturas diferentes para aplicaciones web que se implementarán utilizando Java. Las respuestas a esta pregunta pueden servir como una biblioteca de varios diseños de aplicaciones web con sus pros y sus contras. Aunque me doy cuenta de que las respuestas serán subjetivas, intentemos ser lo más objetivos posible y motivar los pros y los contras que enumeramos.
Use el nivel de detalle que prefiera para describir su arquitectura. Para que su respuesta tenga algún valor, al menos tendrá que describir las principales tecnologías e ideas utilizadas en la arquitectura que describe. Y por último pero no menos importante, ¿ cuándo deberíamos usar su arquitectura?
Yo empezare...
Vista general de la arquitectura
Utilizamos una arquitectura de 3 niveles basada en estándares abiertos de Sun como Java EE, Java Persistence API, Servlet y Java Server Pages.
- Persistencia
- Negocio
- Presentación
Los posibles flujos de comunicación entre las capas están representados por:
Persistence <-> Business <-> Presentation
Lo cual significa, por ejemplo, que la capa de presentación nunca llama o realiza operaciones de persistencia, siempre lo hace a través de la capa de negocios. Esta arquitectura está diseñada para satisfacer las demandas de una aplicación web de alta disponibilidad.
Persistencia
Realiza CRUD persistencia de creación, lectura, actualización y eliminación ( CRUD ). En nuestro caso, estamos utilizando ( Java Persistence API ) JPA y actualmente usamos Hibernate como nuestro proveedor de persistencia y usamos su EntityManager .
Esta capa se divide en múltiples clases, donde cada clase trata con un cierto tipo de entidades (es decir, las entidades relacionadas con un carrito de compras pueden ser manejadas por una única clase de persistencia) y es utilizada por un solo administrador .
Además, esta capa también almacena entidades JPA que son cosas como Account
, ShoppingCart
, etc.
Negocio
Toda la lógica que está vinculada a la funcionalidad de la aplicación web se encuentra en esta capa. Esta funcionalidad podría iniciar una transferencia de dinero para un cliente que desea pagar un producto en línea utilizando su tarjeta de crédito. También podría ser crear un nuevo usuario, eliminar un usuario o calcular el resultado de una batalla en un juego basado en la web.
Esta capa se divide en varias clases y cada una de estas clases se anota con @Stateless
para convertirse en un Bean de sesión sin estado (SLSB). Cada SLSB se denomina administrador y, por ejemplo, un administrador podría ser una clase anotada como mencionada llamada AccountManager
.
Cuando AccountManager
necesita realizar operaciones CRUD, realiza las llamadas apropiadas a una instancia de AccountManagerPersistence
, que es una clase en la capa de persistencia. Un boceto de dos métodos en AccountManager
podría ser:
...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
Usamos las transacciones del gestor de contenedores para que no tengamos que hacer demarcación de transacciones de nuestra propia cuenta. Lo que básicamente ocurre bajo el capó es que iniciamos una transacción cuando ingresamos el método SLSB y lo comprometemos (o lo restituimos) inmediatamente antes de salir del método. Es un ejemplo de convención sobre la configuración, pero no hemos tenido la necesidad de nada más que el valor predeterminado, Requerido, todavía.
Así es como el Tutorial de Java EE 5 de Sun explica el atributo de transacción requerido para Enterprise JavaBeans (EJB):
Si el cliente se ejecuta dentro de una transacción e invoca el método enterprise bean, el método se ejecuta dentro de la transacción del cliente. Si el cliente no está asociado con una transacción, el contenedor inicia una nueva transacción antes de ejecutar el método.
El atributo Requerido es el atributo de transacción implícito para todos los métodos enterprise bean que se ejecutan con la demarcación de transacciones gestionadas por contenedor. Por lo general, no establece el atributo Requerido a menos que necesite anular otro atributo de transacción. Debido a que los atributos de transacción son declarativos, puede cambiarlos fácilmente más adelante.
Presentación
Nuestra capa de presentación está a cargo de ... presentación! Es responsable de la interfaz de usuario y muestra información al usuario creando páginas HTML y recibiendo comentarios de los usuarios a través de solicitudes GET y POST. Actualmente estamos usando la antigua combinación Servlet + Java Server Pages ( JSP ).
La capa llama a los métodos en los gerentes de la capa de negocios para realizar operaciones solicitadas por el usuario y para recibir información para mostrar en la página web. A veces, la información que se recibe de la capa de negocios es de tipos menos complejos como los de String
e int
egers, y en otras ocasiones las entidades de JPA .
Pros y contras con la arquitectura
Pros
- Tener todo lo relacionado con una forma específica de hacer persistencia en esta capa solo significa que podemos pasar de usar JPA a otra cosa, sin tener que volver a escribir nada en la capa de negocios.
- Es fácil para nosotros cambiar nuestra capa de presentación en otra cosa, y es probable que lo hagamos si encontramos algo mejor.
- Dejar que el contenedor EJB administre los límites de las transacciones es bueno.
- El uso de + JPA de Servlet es fácil (para empezar) y las tecnologías son ampliamente utilizadas e implementadas en muchos servidores.
- Se supone que usar Java EE nos facilitará la creación de un sistema de alta disponibilidad con balanceo de carga y conmutación por error . Ambos creemos que debemos tener.
Contras
- Usando JPA puede almacenar consultas de uso frecuente como consultas con nombre utilizando la anotación
@NamedQuery
en la clase de entidad JPA. Si tiene tanto como sea posible relacionado con la persistencia en las clases de persistencia, como en nuestra arquitectura, esto extenderá las ubicaciones donde puede encontrar consultas para incluir también las entidades de JPA. Será más difícil tener una visión general de las operaciones de persistencia y, por lo tanto, será más difícil de mantener. - Tenemos entidades JPA como parte de nuestra capa de persistencia. Pero
Account
yShoppingCart
, ¿no son realmente objetos comerciales? Se hace de esta manera ya que debes tocar estas clases y convertirlas en entidades que JPA sabe cómo manejar. - Las entidades JPA, que también son nuestros objetos comerciales, se crean como Objetos de transferencia de datos ( DTO ), también conocidos como Objetos de valor (VO). Esto da como resultado un modelo de dominio anémico ya que los objetos comerciales no tienen lógica propia, excepto los métodos de acceso. Toda la lógica es realizada por nuestros gerentes en la capa de negocios, lo que resulta en un estilo de programación más procesal. No es un buen diseño orientado a objetos, pero tal vez eso no sea un problema. (Después de todo, la orientación del objeto no es el único paradigma de programación que ha generado resultados).
- El uso de EJB y Java EE presenta un poco de complejidad. Y no podemos usar puramente Tomcat (agregar un microcontenedor EJB no es puramente Tomcat).
- Hay muchos problemas con el uso de + JPA de Servlet. Use Google para obtener más información sobre estos problemas.
- Como las transacciones se cierran al salir de la capa empresarial, no podemos cargar ninguna información de las entidades JPA que esté configurada para cargarse desde la base de datos cuando sea necesaria (utilizando
fetch=FetchType.LAZY
) desde el interior de la capa de presentación. Activará una excepción. Antes de devolver una entidad que contenga estos tipos de campos, debemos asegurarnos de llamar a los captadores relevantes. Otra opción es usar Java Persistence Query Language ( JPQL ) y hacer unFETCH JOIN
. Sin embargo, estas dos opciones son un poco engorrosas.
En mi humilde opinión, la mayoría de nosotros tenemos un denominador común. Al menos en el back-end, tenemos alguna forma de contenedor IOC / DI y un marco de persistencia. Personalmente utilizo Guice y Mybatis para esto. Las diferencias están en cómo implementamos la vista / UI / capa de presentación. Aquí hay 2 opciones principales (puede ser más). Basado en acciones (URL asignadas a los controladores) y basado en componentes. Actualmente estoy usando la capa de presentación basada en componentes (usando wicket). Se asemeja perfectamente a un entorno de escritorio donde uso componentes y eventos en lugar de URL y controladores. Actualmente estoy buscando una razón por la que debería migrar a este tipo de arquitectura de controlador de URL (así es como terminé en esta página). Por qué el bombo sobre las arquitecturas RESTful y Stateless.
Para responder a esta pregunta en pocas palabras: escribo aplicaciones web con estado usando un marco orientado a componentes sobre el contenedor Guice IOC y pongo datos en una base de datos relacional usando Mybatis.
He trabajado en proyectos que usan ese patrón de gerente rígido. Históricamente, fui un gran defensor de la rígida jerarquía en la que todo encajaba en una ordenada caja. A medida que avanzo en mi carrera, me parece forzado en muchos casos. Creo que la adopción de una mentalidad más ágil hacia el diseño de aplicaciones conduce a un mejor producto. Lo que quiero decir con esto es crear un conjunto de clases que resuelvan el problema en cuestión. En lugar de decir "¿Creaste un gerente para esto y lo otro?"
El proyecto actual en el que estoy trabajando es una aplicación web con una combinación de llamadas Spring MVC y RestEasy JSON / Ajax. En el lado del servidor integrado en nuestros controladores hay un nivel de datos basado en fachada sensible con JPA / Hibernate para el acceso directo a la base de datos, algunos accesos a EJB y algunas llamadas al servicio web basadas en SOAP. Unir todo esto es un código de controlador de Java personalizado que determina qué serializar como JSON y devolver al cliente.
No pasamos casi nada de tiempo intentando crear un patrón unificado, sino que optamos por adoptar la idea "Peor es mejor" de la Filosofía de diseño de Unix. Siendo así, es mucho mejor colorear fuera de las líneas y construir algo sensato, rápidamente que construir algo que se adhiera a un montón de estrictos mandatos de diseño.
Lo que hemos seguido en nuestro proyecto es:
Tecnología de front end
- AngularJS
- HTML5
- css3
- Javascript
- Bootstrap 3
API
- DESCANSO
- JERSEY (JAX-RS)
- ESTÁ SEGURO
- BOTA DE PRIMAVERA
- Jackson
- seguridad de primavera
Lógica de negocios
Datos de primavera
Datos de SPRING MongoDB
Base de datos
- MongoDB
Servidor (para el almacenamiento en caché)
- redis
Los componentes en la arquitectura de aplicaciones web incluyen:
1: Navegador: interacción del cliente
HTML
JavaScript
Stylesheet
2: Internet
3: servidor web
CSS
Image
Pages(Java render )
4: servidor de aplicaciones
App Webapp (Java interaction)
Others WebApps
5: Servidor de base de datos
Oracle, SQL, MySQL
6: datos
Ok, haré una (más corta):
- Frontend: Tapestry (3 para proyectos más antiguos, 5 para proyectos más nuevos)
- Capa de negocios: primavera
- DAO''s: Ibatis
- Base de datos: Oracle
Usamos soporte de transacciones Sping e iniciamos transacciones al ingresar a la capa de servicio, propagándonos hacia las llamadas de DAO. La capa de Servicio tiene el mayor conocimiento del modelo de negocio, y los DAO hacen un trabajo CRUD relativamente simple.
Algunas consultas más complicadas en el backend se ocupan de cuestiones de consulta más complicadas por motivos de rendimiento.
Las ventajas de usar Spring en nuestro caso es que podemos tener instancias dependientes de país / idioma, que están detrás de una clase Spring Proxy. Según el usuario de la sesión, se utiliza la implementación correcta de país / idioma al hacer una llamada.
La gestión de transacciones es casi transparente, se revierte en excepciones de tiempo de ejecución. Usamos excepciones sin marcar tanto como sea posible. Solíamos hacer excepciones marcadas, pero con la introducción de Spring veo los beneficios de las excepciones no revisadas, solo manejo excepciones cuando puedes. Evita muchas cosas repetidas de "catch / rethrow" o "throws".
Lo siento, es más corto que tu publicación, espero que te parezca interesante ...
Todavía estamos usando la pila habitual Struts-Spring-Hibernate.
Para futuras aplicaciones, estamos buscando Spring Web Flow + Spring MVC + Hibernate o Spring + Hibernate + Web Services con Flex front end.
Una característica distintiva de nuestra arquitectura es la modularización. Tenemos una cantidad de módulos, algunos comenzando con 3 hasta un máximo de 30 tablas en la base de datos. La mayoría de los módulos consisten en proyectos comerciales y web. El proyecto empresarial tiene lógica de negocios y persistencia mientras que la web tiene lógica de presentación.
En el nivel lógico, hay tres capas: Negocio, Persistencia y Presentación.
Dependencias:
La presentación depende de Negocios y Persistencia.
La persistencia depende de los negocios.
El negocio no depende de otras capas.
La mayoría de los proyectos empresariales tienen tres tipos de interfaces (nota: no GUI, es una capa de interfaz java programática).
- Interfaz que la presentación está utilizando como cliente
- Interfaz que otros módulos están utilizando cuando son el cliente del módulo.
- Interfaz que se puede usar para fines administrativos del módulo.
A menudo, 1 se extiende 2. De esta manera, es fácil reemplazar una implementación de módulo por otra. Esto nos ayuda a adoptar diferentes clientes e integrarlos más fácilmente. Algunos clientes comprarán solo ciertos módulos y necesitamos integrar la funcionalidad que ya tienen. Como la interfaz y la capa de implementación están separadas, es fácil implementar el módulo ad-hock para ese cliente específico sin afectar los módulos dependientes. Y Spring Framework hace que sea fácil inyectar una implementación diferente.
Nuestra capa de negocios se basa en POJOs. Una tendencia que estoy observando es que estos POJO se parecen a los DTO. Sufrimos de un modelo de dominio anémico . No estoy seguro de por qué sucede esto, pero puede deberse a la simplicidad del dominio del problema de muchos de nuestros módulos, la mayoría del trabajo es CRUD o debido a que los desarrolladores prefieren colocar la lógica en otro lugar.
Un poco diferente, y yo reclamaría más arquitectura java modular aquí. Tenemos:
- Spring WS / Rest / JSP front end
- Spring MVC para la lógica del servicio comercial, que contiene la lógica de la capa de presentación, así como las transacciones de Spring
- Interfaz de comunicación de servicio de componentes, consultada a través de EJB por servicios comerciales. Los EJB establecen sus propios límites de transacción que pueden unirse a las transacciones de Spring.
- Implementaciones de servicios de componentes, nuevamente componentes de Spring
- Capa de integración, MyBatis para integraciones de bases de datos, Spring WS para integraciones de servicios web, otras tecnologías de integración para otros servicios
- Mainframes, bases de datos, otros servicios en otros servidores ...
Además de lo anterior, tenemos los módulos de biblioteca compartida que es un proveedor de funcionalidad común para todos los servicios.
El uso de diferentes capas nos permite el desacople completo y la modularidad que necesitamos. También podemos utilizar completamente la potencia de Java EE y Spring. Nada nos impide usar JSF, por ejemplo, para la interfaz si es necesario.
Comparado con la arquitectura de ejemplo de OP, creo que esto se puede describir como tener cuatro capas principales en lugar de tres, aunque con un giro.
Aquí hay una arquitectura web más en la que he trabajado:
Uno de los principales requisitos es que la aplicación debe admitir dispositivos móviles / otros dispositivos. La aplicación también debe ser extensible o flexible a los cambios en las opciones de tecnología.
Nivel de presentación:
- JSP / JQuery (MVC del lado del cliente)
- Android nativo
- IPhone nativo
Web móvil (HTML5 / CSS3 / Diseño receptivo)
Controladores REST de muelle (pueden cambiar a JAX-RS)
Nivel de servicio comercial:
Spring @Service (puede cambiar a EJB sin estado)
Nivel de acceso a datos:
Spring @Repository (puede cambiar a EJB sin estado)
Nivel de recursos:
Entidades Hibernate (JPA) (Puede cambiar a cualquier ORM)
Puede encontrar más información sobre el libro que sigue esta arquitectura here .
Tecnologías de desarrollo web basadas en Java ideales hoy.
Capa web:
HTML + CSS + Ajax + JQuery
Controlador web / Acción / Capa de procesamiento de solicitudes RESTFul:
Juega Framework
Business Logic / Service Layer:
Utilice Pure Java Code el mayor tiempo posible. Uno puede hacer fusión de servicios web aquí.
Capa de transformación de datos XML / JSon:
XMLTool (Búsqueda en Google Code), JSoup, Google GSon, XStream, JOOX (Búsqueda en el código de Google)
Capa de persistencia:
CRUD: JPA o SienaProject o QueryDSL / Consultas complejas: JOOQ, QueryDSL